MetaTrader5
AK-47 Scalper EA: Dein Trading-Assistent für MetaTrader 5
Willkommen zu unserem heutigen Artikel über den AK-47 Scalper EA, ein leistungsstarker Expert Advisor für den MetaTrader 5. In diesem Beitrag werden wir die Eingabeparameter, die Initialisierung und die Hauptfunktionen dieses Systems durchgehen. 1. Eingabeparameter #define ExtBotName "AK-47 EA" //Bot Name
#define Version "1.00"
//Import inputal class
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
//--- Einführung vordefinierter Variablen für die Lesbarkeit des Codes
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
//--- Eingabeparameter
input string EASettings = "---------------------------------------------"; //-------- <EA Einstellungen> --------
input int InpMagicNumber = 124656; //Magic Number
input string MoneySettings = "---------------------------------------------"; //-------- <Geld Einstellungen> --------
input bool isVolume_Percent = true; //Teilvolumen erlauben
input double InpRisk = 3; //Risiko in Prozent des Kontos (%)
input string TradingSettings = "---------------------------------------------"; //-------- <Trading Einstellungen> --------
input double Inpuser_lot = 0.01; //Lots
input double InpSL_Pips = 3.5 //Stoploss (in Pips)
input double InpTP_Pips = 7 //TP (in Pips) (0 = kein TP)
input int InpMax_slippage = 3 //Maximale Slippage erlauben (in Pips)
input double InpMax_spread = 5 //Maximal erlaubter Spread (in Punkten) (0 = flottierend)
input string TimeSettings = "---------------------------------------------"; //-------- <Handelszeiten Einstellungen> --------
input bool InpTimeFilter = true; //Handelszeitfilter
input int InpStartHour = 2; //Start Stunde
input int InpStartMinute = 30 //Start Minute
input int InpEndHour = 21 //End Stunde
input int InpEndMinute = 0 //End Minute 2. Initialisierung der lokalen Variablen //--- Variablen
int Pips2Points; // slippage 3 pips 3=punkte 30=punkte
double Pips2Double; // Stoploss 15 pips 0.015 0.0150
bool isOrder = false;
int slippage;
long acSpread;
string strComment = "";
CPositionInfo m_position; // Handelspositionsobjekt
CTrade m_trade; // Handelsobjekt
CSymbolInfo m_symbol; // Symbolinfo-Objekt
CAccountInfo m_account; // Kontoinfo-Hülle
COrderInfo m_order; // Objekt für ausstehende Aufträge 3. Hauptcode a/ Initialisierungsfunktion des Expert Advisors //+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten |
//+------------------------------------------------------------------+
int OnInit() {
//3 oder 5 Ziffern Erkennung
//Pip und Punkt
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())) // setzt den Symbolnamen
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/ Tick-Funktion des Expert Advisors //+------------------------------------------------------------------+
//| Tick-Funktion des Expert Advisors |
//+------------------------------------------------------------------+
void OnTick() {
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
Comment("LazyBot\nHandel nicht erlaubt.");
return;
}
MqlDateTime structTime;
TimeCurrent(structTime);
structTime.sec = 0;
//Setze Startzeit
structTime.hour = InpStartHour;
structTime.min = InpStartMinute;
datetime timeStart = StructToTime(structTime);
//Setze Endzeit
structTime.hour = InpEndHour;
structTime.min = InpEndMinute;
datetime timeEnd = StructToTime(structTime);
acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
strComment = "\n" + ExtBotName + " - v." + (string)Version;
strComment += "\nServerzeit = " + TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
strComment += "\nHandelszeit = [" + (string)InpStartHour + "h" + (string)InpStartMinute + " --> " + (string)InpEndHour + "h" + (string)InpEndMinute + "]";
strComment += "\nAktueller Spread = " + (string)acSpread + " Punkte";
Comment(strComment);
//Werte aktualisieren
UpdateOrders();
TrailingStop();
//Dieu kien giao dich theo phien My
if(InpTimeFilter) {
if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
if(!isOrder) OpenOrder();
}
}
else {
if(!isOrder) OpenOrder();
}
} //---Ende der Funktion 3.1 Signalberechnung zur Auftragserteilung //+------------------------------------------------------------------+
//| SIGNAL BERECHNEN UND AUFTRAG SENDEN |
//+------------------------------------------------------------------+
void OpenOrder(){
ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL;//-1;
double TP = 0;
double SL = 0;
string comment = ExtBotName;
//Berechne Lots
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() //Spread prüfen
&& CheckVolumeValue(lot1) //Volumen prüfen
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) //Distanz vom OpenPrice zum Bid prüfen
&& CheckStopLoss(OpenPrice, SL, TP) //Distanz von SL, TP zum OpenPrice prüfen
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL)) //Balance prüfen, wenn der Auftrag ausgeführt wird
{
if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__,"--> OrderSend Fehler ", 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() //Spread prüfen
&& CheckVolumeValue(lot1) //Volumen prüfen
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice) //Distanz vom OpenPrice zum Bid prüfen
&& CheckStopLoss(OpenPrice, SL, TP) //Distanz von SL, TP zum OpenPrice prüfen
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY)) //Balance prüfen, wenn der Auftrag ausgeführt wird
{
if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))// verwende "ORDER_TIME_GTC", wenn das Ablaufdatum = 0
Print(__FUNCTION__,"--> OrderSend Fehler ", m_trade.ResultComment());
}
}
} 3.2 Volumenberechnung //+------------------------------------------------------------------+
//| VOLUMEN BERECHNEN |
//+------------------------------------------------------------------+
// Wir definieren die Funktion zur Berechnung der Positionsgröße und geben das Lot zurück, um zu bestellen.
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 Der EA hat die Funktion "Trailing Stop", SL wird jedes Mal geändert, wenn der Preis sinkt //+------------------------------------------------------------------+
//| TRAILING STOP |
//+------------------------------------------------------------------+
void TrailingStop() {
double SL_in_Pip = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) {
if(m_position.SelectByIndex(i)) { // wählt die Aufträge nach Index für weiteren Zugriff auf seine Eigenschaften
if((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
// Für Kaufauftrag
if(m_position.PositionType() == POSITION_TYPE_BUY) {
//--Berechne SL, wenn sich der Preis ändert
SL_in_Pip = NormalizeDouble(Bid - m_position.StopLoss(), _Digits) / Pips2Double;
if(SL_in_Pip > InpSL_Pips) {
double newSL = NormalizeDouble(Bid - InpSL_Pips * Pips2Double, _Digits);
if(!m_trade.PositionModify(m_position.Ticket(), newSL, m_position.TakeProfit())) {
Print(__FUNCTION__,"--> OrderModify Fehler ", m_trade.ResultComment());
continue
}
}
}
// Für Verkaufsauftrag
else if(m_position.PositionType() == POSITION_TYPE_SELL) {
//--Berechne SL, wenn sich der Preis ändert
SL_in_Pip = NormalizeDouble(m_position.StopLoss() - Bid, _Digits) / Pips2Double;
if(SL_in_Pip > InpSL_Pips){
double newSL = NormalizeDouble(Bid + (InpSL_Pips) * Pips2Double, _Digits);
if(!m_trade.PositionModify(m_position.Ticket(), newSL, m_position.TakeProfit())) {
Print(__FUNCTION__,"--> OrderModify Fehler ", m_trade.ResultComment());
//continue;
}
}
}
}
}
}
//--- Ausstehende Aufträge ändern
for(int i=OrdersTotal()-1; i>=0; i--) {// gibt die Anzahl der aktuellen Aufträge zurück
if(m_order.SelectByIndex(i)) { // wählt den ausstehenden Auftrag nach Index für weiteren Zugriff auf seine Eigenschaften
if(m_order.Symbol() == m_symbol.Name() && m_order.Magic()==InpMagicNumber) {
if(m_order.OrderType() == ORDER_TYPE_BUY_STOP) {
SL_in_Pip = NormalizeDouble(Bid - m_order.StopLoss(), _Digits) / Pips2Double;
if(SL_in_Pip < InpSL_Pips/2) {
double newOP = NormalizeDouble(Bid + (InpSL_Pips/2) * Pips2Double, _Digits);
double newTP = NormalizeDouble(newOP + InpTP_Pips * Pips2Double, _Digits);
double newSL = NormalizeDouble(Bid - (InpSL_Pips/2) * Pips2Double, _Digits);
if(!m_trade.OrderModify(m_order.Ticket(), newOP, newSL, newTP, ORDER_TIME_GTC,0)) {
Print(__FUNCTION__,"--> Modify PendingOrder Fehler!", m_trade.ResultComment());
continue
}
}
}
else if(m_order.OrderType() == ORDER_TYPE_SELL_STOP) {
SL_in_Pip = NormalizeDouble(m_order.StopLoss() - Ask, _Digits) / Pips2Double;
if(SL_in_Pip < InpSL_Pips/2){
double newOP = NormalizeDouble(Ask - (InpSL_Pips/2) * Pips2Double, _Digits);
double newTP = NormalizeDouble(newOP - InpTP_Pips * Pips2Double, _Digits);
double newSL = NormalizeDouble(Ask + (InpSL_Pips/2) * Pips2Double, _Digits);
if(!m_trade.OrderModify(m_order.Ticket(), newOP, newSL, newTP, ORDER_TIME_GTC,0)) {
Print(__FUNCTION__,"--> Modify PendingOrder Fehler!", m_trade.ResultComment());
//continue;
}
}
}
}
}
}
}
Wir hoffen, dass dir dieser Einblick in den AK-47 Scalper EA und dessen Funktionen geholfen hat, mehr über diesen Expert Advisor zu lernen. Wenn du Fragen hast oder mehr über andere Trading-Tools erfahren möchtest, lass es uns in den Kommentaren wissen!
2023.06.12