Accueil Trading Systématique Publication

AK-47 Scalper EA : L'Expert Indispensable pour MetaTrader 5

Pièce jointe
44883.zip (5.94 KB, Télécharger 0 fois)

Bienvenue à tous les traders ! Aujourd'hui, je vais vous parler d'un outil qui pourrait bien améliorer votre expérience de trading sur MetaTrader 5 : l'AK-47 Scalper EA. Cet expert, ou robot de trading, est conçu pour optimiser vos opérations de scalping avec efficacité.

1. Paramètres d'entrée

#define ExtBotName "AK-47 EA" // Nom du Bot
#define Version "1.00"

// Import des classes nécessaires
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>

// Variables prédéfinies pour une meilleure lisibilité du code
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)

// Paramètres d'entrée
input string EASettings = "---------------------------------------------"; // -------- <Paramètres EA> --------
input int InpMagicNumber = 124656; // Numéro magique
input string MoneySettings = "---------------------------------------------"; // -------- <Paramètres de gestion de l'argent> --------
input bool isVolume_Percent = true; // Autoriser le volume en pourcentage
input double InpRisk = 3; // Pourcentage de risque sur le solde (%)
input string TradingSettings = "---------------------------------------------"; // -------- <Paramètres de trading> --------
input double Inpuser_lot = 0.01; // Lots
input double InpSL_Pips = 3.5; // Stop loss (en Pips)
input double InpTP_Pips = 7; // Take Profit (en Pips) (0 = Pas de TP)
input int InpMax_slippage = 3; // Glissement maximum autorisé en Pips.
input double InpMax_spread = 5; // Spread maximum autorisé (en Points) (0 = flottant)
input string TimeSettings = "---------------------------------------------"; // -------- <Paramètres de temps de trading> --------
input bool InpTimeFilter = true; // Filtre de temps de trading
input int InpStartHour = 2; // Heure de début
input int InpStartMinute = 30; // Minute de début
input int InpEndHour = 21; // Heure de fin
input int InpEndMinute = 0; // Minute de fin

2. Initialisation des variables locales

//--- Variables
int Pips2Points; // slippage 3 pips 3=points 30=points
double Pips2Double; // Stop loss 15 pips 0.015
bool isOrder = false;
int slippage;
long acSpread;
string strComment = "";

CPositionInfo m_position; // objet de position de trading
CTrade m_trade; // objet de trading
CSymbolInfo m_symbol; // objet d'information sur le symbole
CAccountInfo m_account; // wrapper d'information sur le compte
COrderInfo m_order; // objet des ordres en attente

3. Code Principal

a/ Fonction d'initialisation de l'Expert

int OnInit() {
    // Détection de 3 ou 5 chiffres
    // Pip et point
    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())) // définit le nom du symbole
        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/ Fonction Tick de l'Expert

void OnTick() {
    if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
        Comment("LazyBot\nTrading non autorisé.");
        return;
    }
    
    MqlDateTime structTime;
    TimeCurrent(structTime);
    structTime.sec = 0;
    
    // Définir l'heure de début
    structTime.hour = InpStartHour;
    structTime.min = InpStartMinute;
    datetime timeStart = StructToTime(structTime);
    
    // Définir l'heure de fin
    structTime.hour = InpEndHour;
    structTime.min = InpEndMinute;
    datetime timeEnd = StructToTime(structTime);
    
    acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
    
    strComment = "\n" + ExtBotName + " - v." + (string)Version;
    strComment += "\nHeure serveur = " + TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
    strComment += "\nTemps de trading = [" + (string)InpStartHour + "h" + (string)InpStartMinute + " --> " + (string)InpEndHour + "h" + (string)InpEndMinute + "]";
    strComment += "\nSpread actuel = " + (string)acSpread + " Points";
    
    Comment(strComment);
    
    // Mise à jour des valeurs
    UpdateOrders();
    
    TrailingStop();
    
    // Conditions de trading selon la session
    if(InpTimeFilter) {
        if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
            if(!isOrder) OpenOrder();
        }
    } else {
        if(!isOrder) OpenOrder();
    }
}

3.1 Calculer le signal pour envoyer des ordres

void OpenOrder() {
    ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL; //-1;
    double TP = 0;
    double SL = 0;
    string comment = ExtBotName;
    
    // Calculer les 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() && CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) && CheckStopLoss(OpenPrice, SL, TP) && 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__, "--> Erreur d'envoi de commande ", 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) && CheckStopLoss(OpenPrice, SL, TP) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY)) {
            if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
                Print(__FUNCTION__, "--> Erreur d'envoi de commande ", m_trade.ResultComment());
        }
    }
}

3.2 Calculer le Volume

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);
        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 Fonction de Trailing Stop

void TrailingStop() {
    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())) {
                // Pour les ordres d'achat
                if(m_position.PositionType() == POSITION_TYPE_BUY) {
                    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__, "--> Erreur de modification de commande ", m_trade.ResultComment());
                            continue;
                        }
                    }
                } else if(m_position.PositionType() == POSITION_TYPE_SELL) {
                    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__, "--> Erreur de modification de commande ", m_trade.ResultComment());
                            continue;
                        }
                    }
                }
            }
        }
    }
    //--- Modifier les ordres en attente
    for(int i = OrdersTotal() - 1; i >= 0; i--) {
        if(m_order.SelectByIndex(i)) {
            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__, "--> Erreur de modification d'ordre en attente !", 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__, "--> Erreur de modification d'ordre en attente !", m_trade.ResultComment());
                            continue;
                        }
                    }
                }
            }
        }
    }
}

Articles connexes

Commentaire (0)