I am quite new to coding in Meta Editor, but I have this code for a MA cross-over strategy, where it should generate orders every time the MA crosses and terminate the orders, when it crosses the opposite way. It does work somtimes, but if I backtest on real data it seems that it is only sometimes it executes and terminates the orders on the MA crossings. I don't understand why it just seems to ignore the crossings at times. I am currently testing it on the 1MIN timeframe for USDJPY back from 2020-01-01. On the photo is an example of one of the orders it creates and two crossings afterwards. The picture is attached.
#property version"1.001"#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
CPositionInfo m_position; // trade position object
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object
CDealInfo m_deal;
inputint MA_1_Period = 130; // Ma period 1inputint MA_2_Period = 13; // Ma period 2inputENUM_MA_METHOD MA_1_Method = MODE_SMA; // Method МА1inputENUM_MA_METHOD MA_2_Method = MODE_SMA; // Method МА2inputENUM_APPLIED_PRICE MA_1_Price = PRICE_LOW; // Applied price МА1inputENUM_APPLIED_PRICE MA_2_Price = PRICE_LOW; // Applied price МА2inputint MA_1_Shift = 0; // shift МА1inputint MA_2_Shift = 1; // Shift МА2inputdouble Lot = 5; // Lotinputint StopLoss = 5000; // Stop loss in pointsinputint TakeProfit = 5000; // Take profit in pointsinputint InpTrailingStopPoints = 5000; // Trailing stop loss in pointsinputbool trailingStopLoss = false; // Enable trailing stop loss//---int New_Bar; // 0/1 Formation of a new bardatetime Time_0; // Time of the start of a new barint PosOpen; // Direction of the crossoverint PosClose; // Direction of the crossoverint all_positions; // Total number of open positionsdouble MA1_0; // Current value of the 1st MAdouble MA1_1; // Previous value of the 1st MAdouble MA2_0; // Current value of the 2nd MAdouble MA2_1; // Previous value of the 2nd MAint PosBuy; // 1 = presence of Buy positionint PosSell; // 1 = presence of Sell position//---int handle_iMA_1; // variable for storing the handle of the iMA indicatorint handle_iMA_2; // variable for storing the handle of the iMA indicator//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
m_symbol.Name(Symbol()); // sets symbol name//--- create handle of the iMA indicator
handle_iMA_1=iMA(m_symbol.Name(),Period(),MA_1_Period,MA_1_Shift,MA_1_Method,MA_1_Price);
//--- if the handle is not createdif(handle_iMA_1==INVALID_HANDLE)
{
//--- report the failure and output the error codePrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- stop the indicator earlyreturn(INIT_FAILED);
}
//--- create handle of the iMA indicator
handle_iMA_2=iMA(m_symbol.Name(),Period(),MA_2_Period,MA_2_Shift,MA_2_Method,MA_2_Price);
//--- if the handle is not createdif(handle_iMA_2==INVALID_HANDLE)
{
//--- report the failure and output the error codePrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- stop the indicator earlyreturn(INIT_FAILED);
}
//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
if (!RefreshRates())
return;
PosBuy = 0;
PosSell = 0;
int openOrders = 0;
all_positions = PositionsTotal(); // Total number of positionsfor (int i = all_positions - 1; i >= 0; i--) // returns the number of open positions
{
if (m_position.SelectByIndex(i)) // Select the position
{
if (m_position.PositionType() == POSITION_TYPE_BUY)// If it's a BUY position
{
PosBuy = 1;
if (CrossPositionClose() == 1) // Close the order if it satisfies the condition CrossPositionClose()=1
{
m_trade.PositionClose(m_position.Ticket());
}
elseif (trailingStopLoss) // Apply trailing stop loss
{
double currentStopLoss = m_position.StopLoss();
double newStopLoss = m_symbol.Ask() - InpTrailingStopPoints * m_symbol.Point();
if (newStopLoss > currentStopLoss) {
double takeProfit = m_position.TakeProfit();
if (OrderSelect(m_position.Ticket(), SELECT_BY_TICKET)) {
OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, takeProfit, 0);
}
}
}
}
if (m_position.PositionType() == POSITION_TYPE_SELL) // If it's a SELL position
{
PosSell = 1;
if (CrossPositionClose() == 2) // Close the order if it satisfies the condition CrossPositionClose()=2
{
m_trade.PositionClose(m_position.Ticket());
}
elseif (trailingStopLoss) // Apply trailing stop loss
{
double currentStopLoss = m_position.StopLoss();
double newStopLoss = m_symbol.Bid() + InpTrailingStopPoints * m_symbol.Point();
if (newStopLoss < currentStopLoss) {
double takeProfit = m_position.TakeProfit();
if (OrderSelect(m_position.Ticket(), SELECT_BY_TICKET)) {
OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, takeProfit, 0);
}
}
}
}
}
}
New_Bar=0; // Resetif(Time_0!=iTime(m_symbol.Name(),Period(),0)) // If it's a new bar with a different start time
{
New_Bar=1; // It's a new bar
Time_0=iTime(m_symbol.Name(),Period(),0); // Remember the start time of the new bar
}
MA1_0=iMAGet(handle_iMA_1,0); // Current value of the 1st MA
MA1_1=iMAGet(handle_iMA_1, 1); // Previous value of the 1st MA
MA2_0=iMAGet(handle_iMA_2, 0); // Current value of the 2nd MA
MA2_1=iMAGet(handle_iMA_2, 1); // Previous value of the 2nd MAif(CrossPositionOpen()==1 && New_Bar==1) // Downward to upward movement = open Buy
{
OpenBuy();
}
if(CrossPositionOpen()==2 && New_Bar==1) // Upward to downward movement = open Sell
{
OpenSell();
}
return;
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int CrossPositionOpen()
{
PosOpen=0;
if((MA1_1 <= MA2_0 && MA1_0 > MA2_0) || (MA1_1 < MA2_0 && MA1_0 >= MA2_0)) // Crossover from below to above
{
PosOpen=1;
}
if((MA1_1 >= MA2_0 && MA1_0 < MA2_0) || (MA1_1 > MA2_0 && MA1_0 <= MA2_0)) // Crossover from above to below
{
PosOpen=2;
}
return(PosOpen); // Return the direction of the crossover
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int CrossPositionClose()
{
PosClose=0;
if((MA1_1 >= MA2_0 && MA1_0<MA2_0) || (MA1_1 > MA2_0 && MA1_0 <= MA2_0)) // Crossover from above to below
{
PosClose=1;
}
if((MA1_1 <= MA2_0 && MA1_0 > MA2_0) || (MA1_1 <MA2_0 && MA1_0 >= MA2_0)) // Crossover from below to above
{
PosClose=2;
}
return(PosClose); // Return the direction of the crossover
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void OpenBuy()
{
if(all_positions==1)
{
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positionsif(m_position.SelectByIndex(i))
if(m_position.PositionType()==POSITION_TYPE_BUY)
return; // If it's a Buy position, do not open
}
if(!RefreshRates())
return;
double stopLossPrice = m_symbol.Ask() - StopLoss * m_symbol.Point();
double takeProfitPrice = m_symbol.Ask() + TakeProfit * m_symbol.Point();
m_trade.Buy(Lot, m_symbol.Name(), m_symbol.Ask(), stopLossPrice, takeProfitPrice, "Buy: MA_cross_Method_PriceMode");
return;
}
void OpenSell()
{
if(all_positions==1)
{
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positionsif(m_position.SelectByIndex(i))
if(m_position.PositionType()==POSITION_TYPE_SELL)
return; // If it's a Sell position, do not open
}
if(!RefreshRates())
return;
double stopLossPrice = m_symbol.Bid() + StopLoss * m_symbol.Point();
double takeProfitPrice = m_symbol.Bid() - TakeProfit * m_symbol.Point();
m_trade.Sell(Lot, m_symbol.Name(), m_symbol.Bid(), stopLossPrice, takeProfitPrice, "Sell: MA_cross_Method_PriceMode");
return;
}
//+------------------------------------------------------------------+//| Refreshes the symbol quotes data |//+------------------------------------------------------------------+bool RefreshRates()
{
// Refresh ratesif(!m_symbol.RefreshRates())
return(false);
// Protection against zero return valueif(m_symbol.Ask()==0 || m_symbol.Bid()==0)
return(false);
return(true);
}
//+------------------------------------------------------------------+//| Get value of buffers for the iMA |//+------------------------------------------------------------------+double iMAGet(constint handle,constint index)
{
double MA[];
ArraySetAsSeries(MA,true);
// Reset error codeResetLastError();
// Fill a part of the iMABuffer array with values from the indicator buffer that has an index of 0if(CopyBuffer(handle,0,0,index+1,MA)<0)
{
// If the copying fails, output the error codePrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
// Return 0.0 to indicate that the indicator is not calculatedreturn(0.0);
}
return(MA[index]);
}
Allow the use of cookies to log in to the MQL5.com website.
Please enable the necessary setting in your browser, otherwise you will not be able to log in.
You are signed in. Two-factor authentication has been disabled. Set it up again and scan a new QR code, or continue with two-factor authentication disabled.
Hey,
I am quite new to coding in Meta Editor, but I have this code for a MA cross-over strategy, where it should generate orders every time the MA crosses and terminate the orders, when it crosses the opposite way. It does work somtimes, but if I backtest on real data it seems that it is only sometimes it executes and terminates the orders on the MA crossings. I don't understand why it just seems to ignore the crossings at times. I am currently testing it on the 1MIN timeframe for USDJPY back from 2020-01-01. On the photo is an example of one of the orders it creates and two crossings afterwards. The picture is attached.