AK-47 Scalper EA: Solusi Cerdas untuk Trading di MetaTrader 5

Mike 2023.06.12 03:06 47 0 0
Lampiran

Hai, Sobat Trader! Kali ini kita akan membahas tentang AK-47 Scalper EA, sebuah sistem trading yang dirancang khusus untuk platform MetaTrader 5. EA ini bisa jadi teman setia kamu dalam meraih profit. Yuk, kita intip lebih dalam!

1. Parameter Input

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

//Import kelas input
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>

//--- mendefinisikan variabel untuk keterbacaan kode
#define Ask    SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid    SymbolInfoDouble(_Symbol, SYMBOL_BID)

//--- parameter input
input string  EASettings         = "---------------------------------------------"; //-------- <Pengaturan EA> --------
input int      InpMagicNumber    = 124656;   //Nomor Magic
input string  MoneySettings      = "---------------------------------------------"; //-------- <Pengaturan Uang> --------
input bool     isVolume_Percent  = true;     //Izinkan Volume Persen
input double   InpRisk           = 3;        //Persentase Risiko dari Saldo (%)
input string  TradingSettings    = "---------------------------------------------"; //-------- <Pengaturan Trading> --------
input double   Inpuser_lot       = 0.01;     //Lots
input double   InpSL_Pips        = 3.5;      //Stoploss (dalam Pips)
input double   InpTP_Pips        = 7;        //TP (dalam Pips) (0 = Tanpa TP)
input int      InpMax_slippage   = 3;        //Maksimum slippage yang diizinkan (dalam Pips)
input double   InpMax_spread     = 5;        //Maksimum spread yang diizinkan (dalam Point) (0 = mengambang)
input string   TimeSettings      = "---------------------------------------------"; //-------- <Pengaturan Waktu Trading> --------
input bool     InpTimeFilter     = true;     //Filter Waktu Trading
input int      InpStartHour      = 2;        //Jam Mulai
input int      InpStartMinute    = 30;       //Menit Mulai
input int      InpEndHour        = 21;       //Jam Selesai
input int      InpEndMinute        = 0;        //Menit Selesai

2. Inisialisasi Variabel Lokal

//--- Variabel
int      Pips2Points;    // slippage  3 pips    3=points    30=points
double   Pips2Double;    // Stoploss 15 pips    0.015      0.0150
bool     isOrder = false;
int      slippage;
long     acSpread;
string   strComment = "";

CPositionInfo  m_position;                   // objek posisi trading
CTrade         m_trade;                      // objek trading
CSymbolInfo    m_symbol;                     // objek info simbol
CAccountInfo   m_account;                    // pembungkus info akun
COrderInfo     m_order;                      // objek order yang tertunda

3. Kode Utama

a/ Fungsi inisialisasi Expert

//+------------------------------------------------------------------+
//| Fungsi inisialisasi Expert                                   |
//+------------------------------------------------------------------+
int OnInit() {

   //deteksi 3 atau 5 digit
   //Pip dan 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())) // set nama simbol
      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/ Fungsi tick Expert

//+------------------------------------------------------------------+
//| Fungsi tick Expert                                             |
//+------------------------------------------------------------------+
void OnTick() {

   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
      Comment("LazyBot\nTrading tidak diizinkan.");
      return;
   }
     
   MqlDateTime structTime;
   TimeCurrent(structTime);
   structTime.sec = 0;
   
   //Set waktu mulai
   structTime.hour = InpStartHour;
   structTime.min = InpStartMinute;       
   datetime timeStart = StructToTime(structTime);
   
   //Set waktu selesai
   structTime.hour = InpEndHour;
   structTime.min = InpEndMinute;
   datetime timeEnd = StructToTime(structTime);
   
   acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
   
   
   strComment = "
" + ExtBotName + " - v." + (string)Version;
   strComment += "
Waktu server = " + TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
   strComment += "
Waktu trading = [" + (string)InpStartHour + "h" + (string)InpStartMinute + " --> " +  (string)InpEndHour + "h" + (string)InpEndMinute + "]";
   
   strComment += "
Spread Saat Ini = " + (string)acSpread + " Points";
   
   Comment(strComment);
   
   //Perbarui Nilai
   UpdateOrders();
   
   TrailingStop();
      
   //Kondisi trading sesuai sesi
   if(InpTimeFilter) {
      if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
         if(!isOrder) OpenOrder();
      }
   }
   else {
      if(!isOrder) OpenOrder();
   }
   
} //---Akhir fungsi

3.1 Menghitung sinyal untuk mengirim order

//+------------------------------------------------------------------+
//| HITUNG SINYAL DAN KIRIM ORDER                                  |
//+------------------------------------------------------------------+
void OpenOrder(){
   
   ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL;//-1;
  
   double TP = 0;
   double SL = 0;
   string comment = ExtBotName;
   
   //Hitung 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()                                             //Cek Spread
         && CheckVolumeValue(lot1)                                      //Cek volume
         && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice)  //Cek Jarak dari openPrice ke Bid
         && CheckStopLoss(OpenPrice,  SL, TP)                           //Cek Jarak dari SL, TP ke OpenPrice
         && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL)) //Cek Saldo saat perintah diizinkan
      {
         if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
         Print(__FUNCTION__,"--> OrderSend error ", 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()                                             //Cek Spread
         && CheckVolumeValue(lot1)                                      //Cek volume
         && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice)   //Cek Jarak dari openPrice ke Bid
         && CheckStopLoss(OpenPrice,  SL, TP)                           //Cek Jarak dari SL, TP ke OpenPrice         
         && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY))  //Cek Saldo saat perintah diizinkan
      {
         if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))// gunakan "ORDER_TIME_GTC" saat tanggal kadaluarsa = 0
         Print(__FUNCTION__,"--> OrderSend error ", m_trade.ResultComment());
      }
   }
   
}

3.2 Menghitung Volume

//+------------------------------------------------------------------+
//| HITUNG VOLUME                                                 |
//+------------------------------------------------------------------+
// Kita mendefinisikan fungsi untuk menghitung ukuran posisi dan mengembalikan lot untuk order.
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 memiliki fungsi "Trailing Stop",  SL akan berubah setiap kali harga berubah (turun)

//+------------------------------------------------------------------+
//| TRAILING STOP                                                    |
//+------------------------------------------------------------------+
void TrailingStop() {

   double SL_in_Pip = 0;

   for(int i = PositionsTotal() - 1; i >= 0; i--) {
      if(m_position.SelectByIndex(i)) {    // memilih order berdasarkan indeks untuk akses lebih lanjut ke propertinya        
         if((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
            // Untuk order Buy
            if(m_position.PositionType() == POSITION_TYPE_BUY) {
               //--Menghitung SL saat harga berubah
               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 error ", m_trade.ResultComment());
                   continue  
              }
            }
            }

            //Untuk Sell Order
            else if(m_position.PositionType() == POSITION_TYPE_SELL) {
               //--Menghitung SL saat harga berubah
               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 error ", m_trade.ResultComment());
                     //continue;  
              }
          }
           }
         }
     }
   }
   
   //--- Modifikasi order yang tertunda  
   for(int i=OrdersTotal()-1; i>=0; i--) {// mengembalikan jumlah order saat ini
      if(m_order.SelectByIndex(i)) {      // memilih order tertunda berdasarkan indeks untuk akses lebih lanjut ke propertinya
         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 error!", 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 error!", m_trade.ResultComment());
                     //continue;  
                  }
               }
             }
      }//---Akhir fungsi
}

Daftar
Komentar 0