MetaTrader5
AK-47 스캘퍼 EA: MetaTrader 5를 위한 효과적인 트레이딩 시스템
안녕하세요, 트레이더 여러분! 오늘은 MetaTrader 5에서 사용할 수 있는 강력한 스캘퍼 EA, "AK-47 EA"에 대해 이야기해보려고 합니다. 이 EA는 스캘핑 전략을 통해 단기 거래에서 수익을 극대화하도록 설계되었습니다. 1. 입력 파라미터 #define ExtBotName "AK-47 EA" // 봇 이름
#define Version "1.00"
// 입력 클래스 가져오기
#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 = 124656; // 매직 넘버
input string MoneySettings = "---------------------------------------------"; //-------- <자금 설정> --------
input bool isVolume_Percent = true; // 볼륨 퍼센트 허용
input double InpRisk = 3; // 잔고의 리스크 비율 (%)
input string TradingSettings = "---------------------------------------------"; //-------- <거래 설정> --------
input double Inpuser_lot = 0.01; // 로트
input double InpSL_Pips = 3.5; // 손절(핍 단위)
input double InpTP_Pips = 7; // 목표 수익(핍 단위) (0 = 목표 수익 없음)
input int InpMax_slippage = 3; // 허용 최대 슬리피지(핍 단위)
input double InpMax_spread = 5; // 허용 최대 스프레드(포인트 단위) (0 = 변동형)
input string TimeSettings = "---------------------------------------------"; //-------- <거래 시간 설정> --------
input bool InpTimeFilter = true; // 거래 시간 필터
input int InpStartHour = 2; // 시작 시간
input int InpStartMinute = 30; // 시작 분
input int InpEndHour = 21 // 종료 시간
input int InpEndMinute = 0 // 종료 분 2. 로컬 변수 초기화 //--- 변수들
int Pips2Points; // 슬리피지 3핍 3=포인트 30=포인트
double Pips2Double; // 손절 15핍 0.015 0.0150
bool isOrder = false;
int slippage;
long acSpread;
string strComment = "";
CPositionInfo m_position; // 거래 포지션 객체
CTrade m_trade; // 거래 객체
CSymbolInfo m_symbol; // 심볼 정보 객체
CAccountInfo m_account; // 계좌 정보 래퍼
COrderInfo m_order; // 미체결 주문 객체 3. 메인 코드 a/ 전문가 초기화 함수 //+------------------------------------------------------------------+
//| 전문가 초기화 함수 |
//+------------------------------------------------------------------+
int OnInit() {
//3 또는 5자리 감지
// 핍과 포인트
if(_Digits % 2 == 1) {
Pips2Double = _Point*10;
Pips2Points = 10;
slippage = 10* InpMax_slippage;
}
else {
Pips2Double = _Point;
Pips2Points = 1;
slippage = InpMax_slippage;
}
if(!m_symbol.Name(Symbol())) // 심볼 이름 설정
return(INIT_FAILED);
RefreshRates();
//---
m_trade.SetExpertMagicNumber(InpMagicNumber);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(slippage);
//---
return(INIT_SUCCEEDED);
} b/ 전문가 틱 함수 //+------------------------------------------------------------------+
//| 전문가 틱 함수 |
//+------------------------------------------------------------------+
void OnTick() {
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
Comment("LazyBot\n거래가 허용되지 않습니다.");
return;
}
MqlDateTime structTime;
TimeCurrent(structTime);
structTime.sec = 0;
// 시작 시간 설정
structTime.hour = InpStartHour;
structTime.min = InpStartMinute;
datetime timeStart = StructToTime(structTime);
// 종료 시간 설정
structTime.hour = InpEndHour;
structTime.min = InpEndMinute;
datetime timeEnd = StructToTime(structTime);
acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
strComment = "\n" + ExtBotName + " - v." + (string)Version;
strComment += "\n서버 시간 = " + TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
strComment += "\n거래 시간 = [" + (string)InpStartHour + "h" + (string)InpStartMinute + " --> " + (string)InpEndHour + "h" + (string)InpEndMinute + "]";
strComment += "\n현재 스프레드 = " + (string)acSpread + " 포인트";
Comment(strComment);
// 값 업데이트
UpdateOrders();
TrailingStop();
// 거래 조건
if(InpTimeFilter) {
if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
if(!isOrder) OpenOrder();
}
}
else {
if(!isOrder) OpenOrder();
}
} //--- 함수 종료 3.1 주문 전송을 위한 신호 계산 //+------------------------------------------------------------------+
//| 신호 계산 및 주문 전송 |
//+------------------------------------------------------------------+
void OpenOrder(){
ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL;//-1;
double TP = 0;
double SL = 0;
string comment = ExtBotName;
// 로트 계산
double lot1 = CalculateVolume();
if(OrdType == ORDER_TYPE_SELL) {
double OpenPrice = Bid - NormalizeDouble(InpSL_Pips/2 * Pips2Double, _Digits);
TP = OpenPrice - NormalizeDouble(InpTP_Pips * Pips2Double, _Digits);
SL = Ask + NormalizeDouble(InpSL_Pips/2 * Pips2Double, _Digits);
if(CheckSpreadAllow() // 스프레드 확인
&& CheckVolumeValue(lot1) // 볼륨 확인
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) // OpenPrice에서 Bid까지의 거리 확인
&& CheckStopLoss(OpenPrice, SL, TP) // SL, TP와 OpenPrice 간의 거리 확인
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL)) // 명령이 실행 가능한지 확인
{
if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__,"--> 주문 전송 오류 ", m_trade.ResultComment());
}
}
else if(OrdType == ORDER_TYPE_BUY) {
double OpenPrice = Ask + NormalizeDouble(InpSL_Pips/2 * Pips2Double, _Digits);
SL = Bid - NormalizeDouble(InpSL_Pips/2 * Pips2Double, _Digits);
if(CheckSpreadAllow() // 스프레드 확인
&& CheckVolumeValue(lot1) // 볼륨 확인
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice) // OpenPrice에서 Bid까지의 거리 확인
&& CheckStopLoss(OpenPrice, SL, TP) // SL, TP와 OpenPrice 간의 거리 확인
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY)) // 명령이 실행 가능한지 확인
{
if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))// 만료일이 0일 때는 "ORDER_TIME_GTC" 사용
Print(__FUNCTION__,"--> 주문 전송 오류 ", m_trade.ResultComment());
}
}
} 3.2 볼륨 계산 //+------------------------------------------------------------------+
//| 볼륨 계산 |
//+------------------------------------------------------------------+
// 포지션 크기를 계산하고 주문할 로트를 반환하는 함수입니다.
double CalculateVolume() {
double LotSize = 0;
if(isVolume_Percent == false) {
LotSize = Inpuser_lot;
}
else {
LotSize = (InpRisk) * m_account.FreeMargin();
LotSize = LotSize /100000;
double n = MathFloor(LotSize/Inpuser_lot);
//Comment((string)n);
LotSize = n * Inpuser_lot;
if(LotSize < Inpuser_lot)
LotSize = Inpuser_lot;
if(LotSize > m_symbol.LotsMax()) LotSize = m_symbol.LotsMax();
if(LotSize < m_symbol.LotsMin()) LotSize = m_symbol.LotsMin();
}
//---
return(LotSize);
}3.3 EA의
2023.06.12