Startseite Systemhandel Beitrag

Lazy Bot MT5: Dein täglicher Trading-Assistent für MetaTrader 5

Anhang
41732.zip (4.52 KB, Herunterladen 0 mal)

Willkommen in der Welt des automatisierten Tradings! Heute stelle ich dir den Lazy Bot MT5 vor, einen cleveren EA (Expert Advisor), der dir hilft, die täglichen Ausbrüche auf dem Markt zu nutzen.

1. Input-Parameter

  • EASettings: "---------------------------------------------"
  • Magic Number: 123456
  • Bot Name: "LazyBot_V1"
  • Lots: 0.01
  • Stoploss (in Pips): 5.0
  • Distanz von [H], [L] zu OP_Preis (in Pips): 0
  • Maximale Slippage: 3 Pips
  • Maximaler Spread (in Pips): 0 (0 = schwankend)
  • Trading-Zeiten:
    • Erlaubte Trading-Zeiten: Ja
    • Startstunde: 7
    • Endstunde: 22
  • Risikomanagement:
    • Volumen Prozent zulassen: Nein
    • Risikoprozent des Kontos (%): 1

2. Lokale Variableninitialisierung

// Lokale Parameter

datetime last;
int totalBars;
int Pips2Points; // Slippage 3 Pips
double Pips2Double; // Stoploss 15 Pips
double slippage;
double acSpread;
string strComment = "";

3. Hauptcode

Der Lazy Bot löscht alle alten Aufträge und sucht den höchsten und niedrigsten Wert der vorherigen Tageskerze. Daraufhin werden zwei ausstehende Aufträge gesetzt: BUY_STOP und SELL_STOP. (Es gibt kein TakeProfit).

a) Expert-Initialisierungsfunktion

int OnInit()
{
    // 3 oder 5 Ziffern Erkennung
    if (_Digits % 2 == 1)
    {
        Pips2Double = _Point * 10;
        Pips2Points = 10;
        slippage = 10 * Inpuser_SLippage;
    }
    else
    {
        Pips2Double = _Point;
        Pips2Points = 1;
        slippage = Inpuser_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) Expert-Tick-Funktion

void OnTick()
{
    if (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false)
    {
        Comment("LazyBot\nTrade nicht erlaubt.");
        return;
    }

    // Handelszeit ermitteln
    MqlDateTime timeLocal;
    MqlDateTime timeServer;

    TimeLocal(timeLocal);
    TimeCurrent(timeServer);

    // Feiertage ignorieren
    if (timeServer.day_of_week == 0 || timeServer.day_of_week == 6)
        return;

    int hourLocal = timeLocal.hour;
    int hourCurrent = timeServer.hour;
    acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

    strComment = "\nLokale Stunde ist = " + hourLocal;
    strComment += "\nAktuelle Stunde ist = " + hourCurrent;
    strComment += "\nSpread ist = " + (string)acSpread;
    strComment += "\nGesamtbalken ist = " + (string)totalBars;

    Comment(strComment);

    // Trailing überprüfen
    TrailingSL();

    if (last != iTime(m_symbol.Name(), PERIOD_D1, 0))
    {
        if (isTradingTime)
        {
            if (hourCurrent >= InpStartHour)
            {
                DeleteOldOrds();
                OpenOrder();
                last = iTime(m_symbol.Name(), PERIOD_D1, 0);
            }
        }
        else
        {
            DeleteOldOrds();
            OpenOrder();
            last = iTime(m_symbol.Name(), PERIOD_D1, 0);
        }
    }
}

3.1 Signal berechnen und Aufträge senden

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

    // Maximale Spread überprüfen
    if (InpMax_spread != 0)
    {
        if (acSpread > InpMax_spread)
        {
            Print(__FUNCTION__, " > aktueller Spread ist größer als der zulässige Spread!...");
            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));

    // Lots berechnen
    double lot1 = CalculateVolume();

    double OpenPrice = m_symbol.NormalizePrice(Bar1High + InpAddPrice_pip * Pips2Double);

    // Für 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__, "--> Buy Fehler");
    }

    // Für 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__, "--> Sell Fehler");
    }
}

3.2 Neuen Tag: Alle alten Aufträge löschen

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 Trailing StopLoss

Die EA hat die Funktion "Trailing StopLoss", die sich jedes Mal ändert, wenn der Preis steigt und somit den Gewinn erhöht.

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();

                // Für Kaufauftrag
                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());
                    }
                }
                // Für Verkaufsauftrag
                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());
                    }
                }
            }
        }
    }
}

3.4 Volumenwert überprüfen

bool CheckVolumeValue(double volume)
{
    double min_volume = m_symbol.LotsMin();
    double max_volume = m_symbol.LotsMax();
    double volume_step = m_symbol.LotsStep();

    if (volume < min_volume || volume > max_volume)
    {
        return (false);
    }

    int ratio = (int)MathRound(volume / volume_step);
    if (MathAbs(ratio * volume_step - volume) > 0.0000001)
    {
        return (false);
    }

    return (true);
}

3.5 Freeze Level überprüfen

bool CheckOrderForFREEZE_LEVEL(ENUM_ORDER_TYPE type, double price)
{
    int freeze_level = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
    bool check = false;

    switch (type)
    {
        case ORDER_TYPE_BUY_STOP:
            check = ((price - Ask) > freeze_level * _Point);
            return (check);
        case ORDER_TYPE_SELL_STOP:
            check = ((Bid - price) > freeze_level * _Point);
            return (check);
    }
    return false;
}

3.6 Geld für den Handel überprüfen

bool CheckMoneyForTrade(string symb, double lots, ENUM_ORDER_TYPE type)
{
    MqlTick mqltick;
    SymbolInfoTick(symb, mqltick);
    double price = mqltick.ask;
    if (type == ORDER_TYPE_SELL)
        price = mqltick.bid;

    double margin, free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
    if (!OrderCalcMargin(type, symb, lots, price, margin))
    {
        Print("Error in ", __FUNCTION__, " code=", GetLastError());
        return (false);
    }
    if (margin > free_margin)
    {
        Print("Nicht genug Geld für ", EnumToString(type), " ", lots, " ", symb, " Error code=", GetLastError());
        return (false);
    }
    return (true);
}

3.7 Stoploss überprüfen

bool CheckStopLoss(double price, double SL)
{
    int stops_level = (int)SymbolInfoInteger(m_symbol.Name(), SYMBOL_TRADE_STOPS_LEVEL);
    if (stops_level != 0)
    {
        PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss und TakeProfit müssen nicht näher als %d Punkte vom Schlusskurs sein", stops_level, stops_level);
    }
    return MathAbs(price - SL) > (stops_level * m_symbol.Point());
}

Hier sind auch einige nützliche Videos über MQL4 und MQL5:

Video MQL4:


Video MQL5:


Verwandte Beiträge

Kommentar (0)