MetaTrader5
AK-47 Scalper EA: Panduan Lengkap untuk MetaTrader 5
Selamat datang, rakan-rakan trader! Hari ini kita akan membincangkan tentang AK-47 Scalper EA, sebuah sistem trading yang direka khusus untuk MetaTrader 5. Sistem ini menggunakan algoritma yang canggih untuk membantu anda mendapatkan keuntungan dalam trading. Mari kita lihat dengan lebih mendalam mengenai ciri-ciri dan cara mengkonfigurasi EA ini.
1. Parameter Input
#define ExtBotName "AK-47 EA" // Nama Bot
#define Version "1.00"
// Import kelas inputal
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
//--- memperkenalkan pembolehubah yang telah ditetapkan untuk kebolehbacaan kod
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
//--- parameter input
input string EASettings = "---------------------------------------------"; //-------- <EA Settings> --------
input int InpMagicNumber = 124656; //Nombor Ajaib
input string MoneySettings = "---------------------------------------------"; //-------- <Money Settings> --------
input bool isVolume_Percent = true; //Benarkan Peratusan Volume
input double InpRisk = 3; //Peratus Risiko dari Baki (%)
input string TradingSettings = "---------------------------------------------"; //-------- <Trading Settings> --------
input double Inpuser_lot = 0.01; //Lot
input double InpSL_Pips = 3.5 //Stoploss (dalam Pips)
input double InpTP_Pips = 7 //TP (dalam Pips) (0 = Tiada TP)
input int InpMax_slippage = 3 //Slippage maksimum yang dibenarkan Pips.
input double InpMax_spread = 5 //Spread maksimum yang dibenarkan (dalam Point) (0 = mengambang)
input string TimeSettings = "---------------------------------------------"; //-------- <Trading Time Settings> --------
input bool InpTimeFilter = true; //Penapis Waktu Trading
input int InpStartHour = 2; //Jam Mula
input int InpStartMinute = 30 //Minit Mula
input int InpEndHour = 21 //Jam Tamat
input int InpEndMinute = 0 //Minit Tamat
2. Inisialisasi Pembolehubah Tempatan
//--- Pembolehubah
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 perdagangan
CTrade m_trade; // objek perdagangan
CSymbolInfo m_symbol; // objek info simbol
CAccountInfo m_account; // pembalut info akaun
COrderInfo m_order; // objek pesanan yang tertunda
3. Kod Utama
a/ Fungsi Inisialisasi Expert
//+------------------------------------------------------------------+
//| Fungsi inisialisasi Expert |
//+------------------------------------------------------------------+
int OnInit() {
//Pengesanan 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())) // menetapkan 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\nPerdagangan tidak dibenarkan.");
return;
}
MqlDateTime structTime;
TimeCurrent(structTime);
structTime.sec = 0;
//Tetapkan waktu mula
structTime.hour = InpStartHour;
structTime.min = InpStartMinute;
datetime timeStart = StructToTime(structTime);
//Tetapkan waktu tamat
structTime.hour = InpEndHour;
structTime.min = InpEndMinute;
datetime timeEnd = StructToTime(structTime);
acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
strComment = "\n" + ExtBotName + " - v." + (string)Version;
strComment += "\nMasa pelayan = " + TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
strComment += "\nWaktu perdagangan = [" + (string)InpStartHour + "j" + (string)InpStartMinute + " --> " + (string)InpEndHour + "j" + (string)InpEndMinute + "]";
strComment += "\nSpread Semasa = " + (string)acSpread + " Poin";
Comment(strComment);
//Kemas kini Nilai
UpdateOrders();
TrailingStop();
//Syarat perdagangan mengikut sesi
if(InpTimeFilter) {
if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
if(!isOrder) OpenOrder();
}
}
else {
if(!isOrder) OpenOrder();
}
} //---Akhir fungsi
3.1 Mengira isyarat untuk menghantar pesanan
//+------------------------------------------------------------------+
//| MENGIRA ISYARAT DAN HANTAR PESANAN |
//+------------------------------------------------------------------+
void OpenOrder(){
ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL;//-1;
double TP = 0;
double SL = 0;
string comment = ExtBotName;
//Mengira 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() //Periksa Spread
&& CheckVolumeValue(lot1) //Periksa volume
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) //Periksa Jarak dari openPrice ke Bid
&& CheckStopLoss(OpenPrice, SL, TP) //Periksa Jarak dari SL, TP ke OpenPrice
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL)) //Periksa Baki ketika arahan dibenarkan
{
if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__,"--> Kesalahan OrderSend ", 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() //Periksa Spread
&& CheckVolumeValue(lot1) //Periksa volume
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice) //Periksa Jarak dari openPrice ke Bid
&& CheckStopLoss(OpenPrice, SL, TP) //Periksa Jarak dari SL, TP ke OpenPrice
&& CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY)) //Periksa Baki ketika arahan dibenarkan
{
if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))// gunakan "ORDER_TIME_GTC" apabila tarikh tamat = 0
Print(__FUNCTION__,"--> Kesalahan OrderSend ", m_trade.ResultComment());
}
}
}
3.2 Mengira Volume
//+------------------------------------------------------------------+
//| MENGIRA VOLUME |
//+------------------------------------------------------------------+
// Kami mendefinisikan fungsi untuk mengira saiz posisi dan mengembalikan lot untuk pesanan.
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 mempunyai 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 pesanan mengikut indeks untuk akses seterusnya kepada sifatnya
if((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
// Untuk pesanan Buy
if(m_position.PositionType() == POSITION_TYPE_BUY) {
//--Mengira SL apabila 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__,"--> Kesalahan OrderModify ", m_trade.ResultComment());
continue
}
}
}
//Untuk Pesanan Jual
else if(m_position.PositionType() == POSITION_TYPE_SELL) {
//--Mengira SL apabila 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__,"--> Kesalahan OrderModify ", m_trade.ResultComment());
//continue;
}
}
}
}
}
//--- Mengubah pesanan tertunda
for(int i=OrdersTotal()-1; i>=0; i--) {// mengembalikan jumlah pesanan semasa
if(m_order.SelectByIndex(i)) { // memilih pesanan tertunda mengikut indeks untuk akses seterusnya kepada sifatnya
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__,"--> Kesalahan Modify PendingOrder!", m_trade.ResultComment());
continue
//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__,"--> Kesalahan Modify PendingOrder!", m_trade.ResultComment());
//continue;
//continue;
}
}
2023.06.12