거래 로봇을 무료로 다운로드 하는 법을 시청해보세요
당사를 Facebook에서 찾아주십시오!
당사 팬 페이지에 가입하십시오
스크립트가 흥미로우신가요?
그렇다면 링크 to it -
하셔서 다른 이들이 평가할 수 있도록 해보세요
스크립트가 마음에 드시나요? MetaTrader 5 터미널에서 시도해보십시오
조회수:
275
평가:
(53)
게시됨:
2022.01.10 11:41
이 코드를 기반으로 한 로봇이나 지표가 필요하신가요? 프리랜스로 주문하세요 프리랜스로 이동

이동 평균 EA는 MetaTrader5 클라이언트 터미널의 스탠다드 팩에 포함되어 있으며 이동 평균 지표를 사용하여 거래하는 EA의 예시입니다.

Moving Average.mq5 파일은 "terminal_data_folder\MQL5\Experts\Examples\Moving Average\"에 있습니다 이 EA는 표준 라이브러리의 다음을 사용한 예입니다.기술적 지표,거래 이력 함수 및트레이딩 클래스. 또한 EA에는 거래 결과를 기반으로 하는 자금 관리 시스템이 포함되어 있습니다.

Expert Advisor의 구조와 작동 방식을 살펴보겠습니다.

1. EA 속성

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2013, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00

처음 5개 행에는 주석이 포함되어 있으며 다음 3개 행은 전처리기 지시문을 사용하여 MQL5 프로그램의 속성(저작권, 링크, 버전)을 설정합니다.#property.

Expert Advisor를 실행하면 이들은 모두 "공통" 탭에 표시됩니다.


그림 1. 이동 평균 EA의 공통 매개변수


1.2. Include Files

이후 #include는 지시문은 "Trade.mqh" 파일을 포함하도록 컴파일러에 지시합니다.

이 파일은 표준 라이브러리의 일부이며 거래 기능에 쉽게 액세스할 수 있는 CTrade 클래스를 포함합니다.

#include <Trade\Trade.mqh>

include file의 이름은 대괄호 "<>;"로 표시되므로 경로는 "terminal_data_folder\Include\" 디렉터리에 상대적으로 설정됩니다.

1.3 Inputs

그런 다음 유형, 이름, 기본값 및 주석으로 이동합니다. 이들의 역할은 그림2. 에 나와 있습니다. 2.

input double MaximumRisk        = 0.02;    // Maximum Risk in percentage
input double DecreaseFactor     = 3;       // Descrease factor
input int    MovingPeriod       = 12;      // Moving Average period
input int    MovingShift        = 6;       // Moving Average shift

MaximumRisk 및 DecreaseFactor 매개변수는 자금 관리에 사용되며, MovingPeriod 및 MovingShift는 이동 평균의 기간 및 이동을 설정합니다.

입력 매개변수 줄의 주석 텍스트는 입력 매개변수 이름 대신 기본값과 함께 "옵션" 탭에 표시됩니다.


그림 2. 이동 평균 EA의 입력 매개변수

1.4. 전역 변수

그런 다음 전역 변수 ExtHandle이 선언됩니다. 이동 평균 지표의 핸들을 보관할 때 사용합니다.

//---
int   ExtHandle=0;

6가지 함수가 있습니다. 각각의 목적은 함수 본문 앞의 주석에 설명되어 있습니다.

  1. TradeSizeOptimized() - 최적의 랏의 크기를 계산합니다.
  2. CheckForOpen() - 매수 진입 조건을 확인합니다.
  3. CheckForClose() - 청산 조건을 확인합니다.
  4. OnInit() - Expert 초기화 함수;
  5. OnTick() - Expert 틱 함수;
  6. OnDeinit() - Expert 초기화 해제 함수;

마지막 세 가지 함수는 이벤트 처리 함수입니다; 처음 세 개의 서비스 함수는 해당 코드에서 호출됩니다.


2. 이벤트 핸들링 함수

2.1. OnInit() 초기화 함수

OnInit() 함수는 Expert Advisor를 처음 시작할 때 한 번 호출됩니다. 일반적으로 OnInit() 이벤트 핸들러에서 EA가 작업을 위해 준비됩니다. 입력 매개변수가 확인되고 표시기 및 매개변수가 초기화되는 등의 기능을 합니다. 심각한 오류의 경우 추가 작업이 의미가 없을 때 반환 코드 INIT_FAILED와 함께 기능이 종료됩니다.

//+------------------------------------------------------------------+
//| Expert 초기화 함수                                                 |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }

EA를 사용한 거래는 이동평균 지표를 기반으로 하기 때문에 iMA()를 호출하여 이동 평균 지표가 생성되고 해당 핸들이 전역 변수 ExtHandle에 저장됩니다.

오류가 발생하면 OnInit()과 반환 코드와 함께 종료됩니다.INIT_FAILED - 초기화에 실패한 경우 EA/indicator 동작을 완료하는 올바른 방법입니다.


2.2. OnTick() 함수

OnTick() 함수는 EA가 실행되는 차트의 심볼에 대해 새 quote가 수신될 때마다 호출됩니다.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(PositionSelect(_Symbol))
      CheckForClose();
   else
      CheckForOpen();
//---
  }

PositionSelect() 함수는 현재 심볼에 대해 포지션을 가지고 있는지 정의하는 데 사용됩니다.

오픈 포지션이 있으면 CheckForClose() 함수가 호출되어 시장의 현재 상태를 분석하고 오픈 포지션을 닫고, 그렇지 않으면 CheckForOpen()을 호출하여 시장 진입 조건을 확인하고 그러한 조건이 있으면 새로운 포지션을 엽니다.


2.3. OnDeInit() 초기화 해제 함수

OnDeInit()는 EA가 차트에서 제거될 때 호출됩니다. 프로그램이 작동 중에 그래픽 객체가 배치 될 경우 그래픽 객체를 차트에서 제거될 수 있습니다.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+

이 경우 Expert Advisor 초기화 해제 중에는 작업이 수행되지 않습니다.


3. Service 함수

3.1. TradeSizeOptimized() 함수

이 함수는 지정된 위험 수준과 거래 결과를 통해 포지션을 열기 위한 최적의 랏의 크기 값을 계산하고 반환합니다.

//+------------------------------------------------------------------+
//| 최적의 랏 사이즈 계산                                                |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- 랏 사이즈를 계산
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2);
//--- 연속적으로 손실을 본 길이를 계산
   if(DecreaseFactor>0)
     {
      //--- 전체 거래 히스토리를 요청
      HistorySelect(0,TimeCurrent());
      //--
      int    orders=HistoryDealsTotal();  // 총 거래수
      int    losses=0;                    // 손실 마감한 거래릐 총수

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- 거래 심볼 확인
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- 수익을 확인
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- 노멀라이징과 가능한 거래량을 체크
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- 거래량값을 반환
   return(lot);
  }

SymbolInfoDouble() 함수는 현재 심볼에 대한 가격 가용성을 확인하는 데 사용됩니다. OrderCalcMargin() 함수는 주문(이 경우 매수 주문)에 필요한 마진을 요청하는 데 사용됩니다. 초기 랏 사이즈는 주문에 필요한 증거금, 계좌의 여유 증거금(AccountInfoDouble(ACCOUNT_FREEMARGIN)) 및 입력 매개변수 MaximumRisk에 지정된 위험의 최대 허용 값입니다.

입력 매개변수 DecreaseFactor의 값이 양수이면 히스토리의 거래가 분석되고 최대 손실 거래 시리즈에 대한 정보를 고려하여 랏의 크기가 조정됩니다. 초기 랏 크기는 다음에 따라 계산됩니다; 크기(1-손실/ 감소 계수)가 곱해짐.

그런 다음 거래량은 현재 심볼에 대해 허용되는 최소 거래량 단계(stepvol)의 배수인 값으로 "반올림"됩니다. 또한 거래량의 최소값(minvol)과 최대 가능값(maxvol)을 요청하며, 랏 값이 허용한도를 벗어날 경우 조정됩니다. 결과적으로 함수는 거래량이 계산된 값을 반환합니다.


3.2. Function CheckForOpen()

CheckForOpen()은 포지션에 진입할 조건을 확인하는 데 사용되며 거래 조건이 발생할 때(이 경우 가격이 이동 평균을 교차할 때) 포지션 진입합니다.

//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   MqlRates rt[2];
//--- 가격 값을 복사
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
//--- 새로운 바의 첫번째 틱에서만 거래
   if(rt[1].tick_volume>1)
      return;
//--- 이동 평균 지표의 현재값을 인식 
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- 신호를 체크
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

   if(rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=ORDER_TYPE_SELL;    // 매도 조건
   else
     {
      if(rt[0].open<ma[0] && rt[0].close>ma[0])
         signal=ORDER_TYPE_BUY;  // 매수 조건
     }
//--- 추가적인 체크
   if(signal!=WRONG_VALUE)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               0,0);
           }
//---
  }

이동 평균을 이용하여 매매할 때는 가격이 이동평균선을 넘는지 확인해야 합니다. CopyRates() 함수를 사용하여 현재 가격의 두 값의 구조가 rt[]의 배열에 복사되고, rt[1]은 현재 바에 해당하며, rt[0]는 완료된 바에 해당합니다.

현재 바의 틱 볼륨이 1이면 새 막대가 시작됩니다. 새로운 바를 감지하는 이 방법은 어떤 경우에는 실패할 수 있으므로(쿼트가 크게 묶여 올 때) 새로운 막대의 형성이 시작되는 것은 현재 쿼트의 시간을 저장하고 비교하여 수행해야 합니다(참조IsNewBar).

이동 평균 지표의 현재 값은 CopyBuffer()를 사용하여 요청되고 지표값은 하나의 값만 포함하는 ma[] 배열에 저장됩니다. 그런 다음 프로그램은 가격이 이동 평균을 교차했는지 확인하고 추가 확인을 수행합니다(EA를 사용한 거래가 가능하고 바가 기록에 있는 경우). 성공하면 트레이딩 객체의 메서드(CTrade 인스턴스) PositionOpen()을 호출하여 적절한 포지션이 열립니다.

포지션 진입 가격은 신호 변수의 값에 따라 Bid 또는 Ask 가격을 반환하는 SymbolInfoDouble() 함수를 사용하여 설정됩니다. 포지션 볼륨은 위에서 설명한 TradeSizeOptimized()를 호출하여 결정됩니다.


3.3. CheckForClose() 함수

CheckForClose()는 포지션을 청산 할 조건을 확인하고 청산 조건이 발생하면 포지션을 청산합니다.

//+------------------------------------------------------------------+
//| 포지션 청산 조건 확인                                               |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- 가격 값 복사
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
//--- 새로운 바의 첫번째 틱에서만 거래
   if(rt[1].tick_volume>1)
      return;
//--- 이동 평균 지표의 현재 값
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- PositionSelect()을 사용하여 이전에 선택된 포지션 타입을 얻음
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);

   if(type==(long)POSITION_TYPE_BUY   && rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL  && rt[0].open<ma[0] && rt[0].close>ma[0])
      signal=true;
//--- 추가적인 확인
   if(signal)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionClose(_Symbol,3);
           }
//---
  }

CheckForClose() 함수의 알고리즘은 CheckForOpen()의 알고리즘과 유사합니다. 현재 보유중인 포지션의 방향에 따라 청산 조건이 다시 확인됩니다(가격이 MA를 하향 교차하면 매수 또는 상향 교차하면 매도). 보유중인 포지션은 트레이드 오브젝트의(예:씨트레이드) PositionClose() 메서드를 호출하여 청산됩니다.


4. 백테스팅

매개 변수의 최상의 값은 MetaTrader 5 터미널의 전략 테스터를 사용하여 찾을 수 있습니다.

예를 들어, 2012.01.01-2013.08.01 기간에서 MovingPeriod 매개변수를 최적화 할 경우 MovingPeriod=45일 때 최상의 결과를 얻을 수 있습니다.

이동 평균 Expert Advisor의 백테스팅 결과

이동 평균 Expert Advisor의 백테스팅 결과

결과:

표준 팩에 포함된 메타 트레이더 5 터미널의 이동 평균 Expert Advisor는 표준 라이브러리의 기술 지표,거래 내역 함수 및 거래 클래스를 사용하는 예입니다. 또한 EA에는 거래 결과를 기반으로 하는 자금 관리 시스템이 포함되어 있습니다.


MetaQuotes Ltd에서 러시아어로 번역함.
원본 코드: https://www.mql5.com/ru/code/1921

MQL5 마법사 - 모닝 이브닝 스타스 + RSI에 기반한 매매 신호 MQL5 마법사 - 모닝 이브닝 스타스 + RSI에 기반한 매매 신호

Relative Strength Index (RSI)에 기반한 "모닝 스타/이브닝 스타" 캔들 스틱 패턴 매매 신호를 살펴봅니다. 이 전략에 기반한 Expert Advisor 코드는 MQL5 마법사를 사용하여 자동으로 생성될 수 있습니다.

MQL5 마법사 - 모닝 이브닝 스타스 + MFI에 기반한 매매 신호 MQL5 마법사 - 모닝 이브닝 스타스 + MFI에 기반한 매매 신호

Market Facilitation Index (MFI)에 기반한 "모닝 스타/이브닝 스타" 캔들 스틱 패턴 매매 신호를 살펴봅니다. 이 전략에 기반한 Expert Advisor 코드는 MQL5 마법사를 사용하여 자동으로 생성될 수 있습니다.

MACD 샘플 MACD 샘플

MACD Sample Expert Advisor는 MACD의 메인 라인과 시그널 라인의 교차점에서 거래합니다. 이 Expert Advisor는 EA 개발에서 객체 지향 접근 방식의 한 예입니다.

정규식 작업을 위한 MQL5의 RegularExpressions 정규식 작업을 위한 MQL5의 RegularExpressions

정규식은 빠르고 유연한 텍스트 처리를 위한 공식적인 언어를 제공합니다. 각 정규식은 정규식 엔진이 소스 텍스트에서 일치 항목을 찾으려고 하는 패턴(마스크)입니다. 패턴은 하나 이상의 character literals, operators, constructs으로 구성됩니다.