Expert Advisor (EA) Automation Code for Multi Moving Average Crossover Strategy
//--- #include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh>
CPositionInfo m_position; // trade position object CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object
//--- input parameters input double Lots = 0.05; // Trading Volume input int FastMA01 = 6; // Fast Line 01 Period input int FastMA02 = 8; // Fast Line 02 Period input int MiddleMA = 16; // Middle Line Period input int SlowMA01 = 30; // Slow Line 01 Period input int SlowMA02 = 28; // Slow Line 02 Period input ulong m_magic=42828093; // Magic Number ulong m_slippage=10; // Slippage
//--- int handle_fastMA01; // Fast Line 01 Handle int handle_fastMA02; // Fast Line 02 Handle int handle_middleMA; // Middle Line Handle int handle_slowMA01; // Slow Line 01 Handle int handle_slowMA02; // Slow Line 02 Handle
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- if(!m_symbol.Name(Symbol())) // Set symbol name return(INIT_FAILED);
RefreshRates();
string err_text='';
if(!CheckVolumeValue(Lots,err_text))
{
Print(err_text);
return(INIT_PARAMETERS_INCORRECT);
}
//---
m_trade.SetExpertMagicNumber(m_magic);
if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))
m_trade.SetTypeFilling(ORDER_FILLING_FOK);
else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))
m_trade.SetTypeFilling(ORDER_FILLING_IOC);
else
m_trade.SetTypeFilling(ORDER_FILLING_RETURN);
m_trade.SetDeviationInPoints(m_slippage);
//--- Create Moving Average handles
handle_fastMA01 = iMA(m_symbol.Name(), PERIOD_M15, FastMA01, 0, MODE_SMA, PRICE_CLOSE);
handle_fastMA02 = iMA(m_symbol.Name(), PERIOD_M15, FastMA02, 0, MODE_SMA, PRICE_CLOSE);
handle_middleMA = iMA(m_symbol.Name(), PERIOD_M15, MiddleMA, 0, MODE_SMA, PRICE_CLOSE);
handle_slowMA01 = iMA(m_symbol.Name(), PERIOD_M15, SlowMA01, 0, MODE_SMA, PRICE_CLOSE);
handle_slowMA02 = iMA(m_symbol.Name(), PERIOD_M15, SlowMA02, 0, MODE_SMA, PRICE_CLOSE);
//--- Check if indicators are created successfully
if(handle_fastMA01 == INVALID_HANDLE || handle_fastMA02 == INVALID_HANDLE || handle_middleMA == INVALID_HANDLE || handle_slowMA01 == INVALID_HANDLE || handle_slowMA02 == INVALID_HANDLE)
{
Print('Failed to create moving average indicators for the symbol ', m_symbol.Name());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- }
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Trade only on new bar open static datetime PrevBars=0; datetime time_0=iTime(0); if(time_0==PrevBars) return; PrevBars=time_0;
//--- Get Moving Average values
double fastMA01 = iMAGet(handle_fastMA01, 0);
double fastMA02 = iMAGet(handle_fastMA02, 0);
double middleMA = iMAGet(handle_middleMA, 0);
double slowMA01 = iMAGet(handle_slowMA01, 0);
double slowMA02 = iMAGet(handle_slowMA02, 0);
double currentClose = iClose(m_symbol.Name(), PERIOD_M15, 0);
//--- Check for open positions
if (m_position.Select(m_symbol.Name(), m_magic))
{
if (m_position.PositionType() == POSITION_TYPE_BUY && currentClose < fastMA02)
{
//--- Close Long Position
m_trade.PositionClose(m_position.Ticket());
}
else if (m_position.PositionType() == POSITION_TYPE_SELL && currentClose > slowMA02)
{
//--- Close Short Position
m_trade.PositionClose(m_position.Ticket());
}
}
//--- Open Long Position
if (currentClose > fastMA01 && currentClose > middleMA && currentClose > slowMA01 && !m_position.Select(m_symbol.Name(), m_magic, POSITION_TYPE_BUY))
{
m_trade.Buy(Lots, m_symbol.Name());
}
//--- Open Short Position
else if (currentClose < fastMA01 && currentClose < middleMA && currentClose < slowMA01 && !m_position.Select(m_symbol.Name(), m_magic, POSITION_TYPE_SELL))
{
m_trade.Sell(Lots, m_symbol.Name());
}
}
//+------------------------------------------------------------------+ //| Refresh symbol data | //+------------------------------------------------------------------+ bool RefreshRates(void) { //--- Refresh rates if(!m_symbol.RefreshRates()) { Print('RefreshRates error'); return(false); }
//--- Check for zero values
if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
return(false);
return(true);
}
//+------------------------------------------------------------------+ //| Check trading volume | //+------------------------------------------------------------------+ bool CheckVolumeValue(double volume, string &error_description) { //--- Minimum allowed volume double min_volume = m_symbol.LotsMin(); if(volume < min_volume) { error_description = StringFormat('Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f', min_volume); return(false); }
//--- Maximum allowed volume
double max_volume = m_symbol.LotsMax();
if(volume > max_volume)
{
error_description = StringFormat('Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f', max_volume);
return(false);
}
//--- Volume step
double volume_step = m_symbol.LotsStep();
int ratio = (int)MathRound(volume / volume_step);
if(MathAbs(ratio * volume_step - volume) > 0.0000001)
{
error_description = StringFormat('Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f',
volume_step,ratio * volume_step);
return(false);
}
error_description = 'Correct volume value';
return(true);
}
//+------------------------------------------------------------------+ //| Check if filling type is allowed | //+------------------------------------------------------------------+ bool IsFillingTypeAllowed(int fill_type) { int filling = m_symbol.TradeFillFlags(); return((filling & fill_type) == fill_type); }
//+------------------------------------------------------------------+ //| Get bar time | //+------------------------------------------------------------------+ datetime iTime(const int index, string symbol=NULL, ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT) { if(symbol == NULL) symbol = m_symbol.Name(); if(timeframe == 0) timeframe = Period(); datetime Time[1]; datetime time = 0; int copied = CopyTime(symbol, timeframe, index, 1, Time); if(copied > 0) time = Time[0]; return(time); }
//+------------------------------------------------------------------+ //| Get iMA indicator buffer value | //| Buffer numbers: | //| 0 - MAIN_LINE, 1 - SIGNAL_LINE | //+------------------------------------------------------------------+ double iMAGet(const int handle, const int index) { double MA[1]; if(CopyBuffer(handle, 0, index, 1, MA) < 0) { Print('Failed to copy data from the moving average indicator'); return(0.0); } return(MA[0]); } //+------------------------------------------------------------------+
原文地址: https://www.cveoy.top/t/topic/fUUG 著作权归作者所有。请勿转载和采集!