시스템트레이딩 게시글

Lazy Bot MT5: 일일 돌파 전략을 위한 EA 소개

첨부파일
41732.zip (4.52 KB, 다운로드 2회)

안녕하세요, 트레이더 여러분! 오늘은 MetaTrader 5에서 사용할 수 있는 Lazy Bot MT5에 대해 자세히 알아보려고 합니다. 이 봇은 매일 자동으로 거래를 진행하며, 특히 일일 고점과 저점을 기준으로 주문을 생성하는 전략을 가지고 있습니다.

1. 입력 매개변수

  • EA 설정
// 외부 클래스 불러오기
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>

// 코드 가독성을 위한 미리 정의된 변수 소개
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)

// 입력 매개변수
input string EASettings = "---------------------------------------------"; // EA 설정
input int InpMagicNumber = 123456; // 매직 넘버
input string InpBotName = "LazyBot_V1"; // 봇 이름
input double Inpuser_lot = 0.01; // 로트 수
input double Inpuser_SL = 5.0; // 손절매 (핍 단위)
input double InpAddPrice_pip = 0; // 고점/저점에서 OP 가격까지의 거리 (핍 단위)
input int Inpuser_SLippage = 3; // 허용되는 최대 슬리피지 (핍 단위)
input double InpMax_spread = 0; // 허용되는 최대 스프레드 (0 = 플로팅)
input bool isTradingTime = true; // 거래 허용 시간
input int InpStartHour = 7; // 시작 시간
input int InpEndHour = 22; // 종료 시간
input bool isVolume_Percent = false; // 볼륨 비율 허용 여부
input double InpRisk = 1; // 잔고 대비 리스크 비율 (%)

2. 로컬 변수 초기화

// 로컬 매개변수
datetime last;
int totalBars;
int Pips2Points; // 슬리피지 3 핍으로 설정
double Pips2Double; // 손절매 15 핍
double slippage;
double acSpread;
string strComment = "";

CPositionInfo m_position; // 거래 포지션 객체
CTrade m_trade; // 거래 객체
CSymbolInfo m_symbol; // 심볼 정보 객체
CAccountInfo m_account; // 계좌 정보 래퍼
COrderInfo m_order; // 보류 중인 주문 객체

3. 주요 코드

Lazy Bot은 매일 이전 일일 바의 고점과 저점을 기준으로 새로운 주문을 생성합니다. 기존의 주문은 삭제되고, 두 개의 보류 주문 "BUY_STOP", "SELL_STOP"이 생성됩니다 (테이크 프로핏 없음).

3.1 신호 계산 및 주문 전송

void OpenOrder()
{
    double TP_Buy = 0, TP_Sell = 0;
    double SL_Buy = 0, SL_Sell = 0;

    // 최대 스프레드 체크
    if (InpMax_spread != 0) {
        if (acSpread > InpMax_spread) {
            Print(__FUNCTION__, " > 현재 스프레드는 사용자 스프레드보다 큽니다!");
            return;
        }
    }
    // 이전 바의 고점 및 저점 계산
    double Bar1High = m_symbol.NormalizePrice(iHigh(m_symbol.Name(), PERIOD_D1, 1));
    double Bar1Low = m_symbol.NormalizePrice(iLow(m_symbol.Name(), PERIOD_D1, 1));

    // 로트 수 계산
    double lot1 = CalculateVolume();
    double OpenPrice = m_symbol.NormalizePrice(Bar1High + InpAddPrice_pip * Pips2Double);

    // BUY_STOP 주문 설정
    SL_Buy = m_symbol.NormalizePrice(OpenPrice - Inpuser_SL * Pips2Double);
    totalBars = iBars(m_symbol.Name(), PERIOD_D1);
    string comment = InpBotName + ";" + m_symbol.Name() + ";" + totalBars;

    if (CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY) && CheckStopLoss(OpenPrice, SL_Buy)) {
        if (!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL_Buy, TP_Buy, ORDER_TIME_GTC, 0, comment)) {
            Print(__FUNCTION__, "--> 매수 주문 오류");
        }
    }
    // SELL_STOP 주문 설정
    OpenPrice = m_symbol.NormalizePrice(Bar1Low - InpAddPrice_pip * Pips2Double);
    SL_Sell = m_symbol.NormalizePrice(OpenPrice + Inpuser_SL * Pips2Double);

    if (CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL) && CheckStopLoss(OpenPrice, SL_Sell)) {
        if (!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL_Sell, TP_Sell, ORDER_TIME_GTC, 0, comment)) {
            Print(__FUNCTION__, "--> 매도 주문 오류");
        }
    }
}

3.2 새로운 날: 모든 이전 주문 삭제

void DeleteOldOrds()
{
    string sep = ";"; // 구분자
    ushort u_sep;
    string result[];

    for (int i = OrdersTotal() - 1; i >= 0; i--) {
        if (m_order.SelectByIndex(i)) {
            u_sep = StringGetCharacter(sep, 0);
            string Ordcomment = m_order.Comment();
            int k = StringSplit(Ordcomment, u_sep, result);

            if (k > 2) {
                string sym = m_symbol.Name();
                if ((m_order.Magic() == InpMagicNumber) && (sym == result[1])) {
                    m_trade.OrderDelete(m_order.Ticket());
                }
            }
        }
    }
}

3.3 EA의 트레일링 손절매 기능

void TrailingSL()
{
    double SL_in_Pip = 0;

    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (m_position.SelectByIndex(i)) {
            if ((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
                double order_stoploss1 = m_position.StopLoss();
                if (m_position.PositionType() == POSITION_TYPE_BUY) {
                    SL_in_Pip = NormalizeDouble((Bid - order_stoploss1), _Digits) / Pips2Double;
                    if (SL_in_Pip > Inpuser_SL) {
                        order_stoploss1 = NormalizeDouble(Bid - (Inpuser_SL * Pips2Double), _Digits);
                        m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
                    }
                } else if (m_position.PositionType() == POSITION_TYPE_SELL) {
                    SL_in_Pip = NormalizeDouble((m_position.StopLoss() - Ask), _Digits) / Pips2Double;
                    if (SL_in_Pip > Inpuser_SL) {
                        order_stoploss1 = NormalizeDouble(Ask + (Inpuser_SL * Pips2Double), _Digits);
                        m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
                    }
                }
            }
        }
    }
}

Lazy Bot MT5를 이용하면 일일 고점과 저점을 기반으로 한 전략으로 보다 체계적인 거래를 할 수 있습니다. 이제 이 EA를 통해 더욱 효율적인 트레이딩을 경험해 보세요!

연관 포스트

댓글 (0)