Okay, here's a breakdown of what this MetaTrader script does, explained in a way that doesn't require any programming knowledge.
This script is designed to automatically trade on the Forex market based on the interaction of two Exponential Moving Averages (EMAs). Think of an EMA as a line that shows the average price of a currency pair over a certain period, with more recent prices having a bigger impact. The script uses two EMAs: a "short" EMA (calculated over a shorter period) and a "long" EMA (calculated over a longer period).
Here's how it works:
-
Setup:
- The script starts by taking in some settings you provide, like how much money to risk on each trade (
Lots), how much profit to aim for (TakeProfit), how much loss you're willing to accept (StopLoss), and how much to trail a stop loss (TrailingStop). It also asks for the periods to be used for short and long EMA calculations (ShortEmaandLongEma), whether to close trades when the EMAs cross in the opposite direction (ExitOnCross), which candle to read as signal (SignalCandle) and a "magic number" (MagicNumber) to help identify trades opened by this specific script.
- The script starts by taking in some settings you provide, like how much money to risk on each trade (
-
Finding a Crossover:
- The core of the script is identifying when the short EMA crosses the long EMA. A cross happens when the short-term average price moves above or below the long-term average price.
- If the short EMA crosses above the long EMA, it's seen as a potential signal to buy (because short-term prices are rising faster than long-term prices, suggesting an upward trend).
- If the short EMA crosses below the long EMA, it's seen as a potential signal to sell (because short-term prices are falling faster than long-term prices, suggesting a downward trend).
- The
FreshCross()function looks at the current and previous EMA values to see if a cross has just happened. It waits for the cross to occur, and ignores the first load.
-
Managing Trades:
- The
CheckOpenTrades()function checks if there are any existing trades opened by this script (using the "magic number" to identify them) for the current currency pair. This is important to prevent the script from opening multiple trades when it should only have one.
- The
-
Opening Trades:
- If there are no existing trades and a crossover signal is detected:
- The script will open a "buy" order if the short EMA has crossed above the long EMA.
- The script will open a "sell" order if the short EMA has crossed below the long EMA.
- When opening the trade, the script sets the stop-loss (the maximum loss you're willing to take) and, optionally, a take-profit level (the profit target).
- If there are no existing trades and a crossover signal is detected:
-
Managing Open Trades:
-
If the script finds an open trade that it created, it manages it in two ways:
- Closing on Reverse Cross: If the
ExitOnCrosssetting is enabled, the script will close the trade if the EMAs cross in the opposite direction of the open trade. For example, if the script opened a "buy" order and the short EMA then crosses below the long EMA, it will close the "buy" order, because the signal indicates a possible change in trend direction. - Trailing Stop: The script can also implement a trailing stop. A trailing stop automatically adjusts the stop-loss level as the price moves in your favor. This helps to lock in profits while still giving the trade room to move. For example, if you set a trailing stop of 30 pips (a unit of measure in Forex), the stop-loss will move up 30 pips for every 30 pips the price moves in a profitable direction.
- Closing on Reverse Cross: If the
-
In summary: This script automatically buys or sells a currency pair when a short-term price average crosses above or below a long-term price average, and it can automatically close trades when the averages cross back or when a trailing stop is triggered. It's designed to automate a basic EMA crossover trading strategy.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| EMA_CROSS.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//| |
//| Modified by Robert Hill as follows |
//| 6/4/2006 Fixed bugs and added exit on fresh cross option |
//| Added use of TakeProfit of 0 |
//| Modified for trade on open of closed candle |
//| Added Trades in this symbol and MagicNumber check |
//| to allow trades on different currencies at same time |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| TODO: Add Money Management routine |
//+------------------------------------------------------------------+
#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"
//---- input parameters
extern double TakeProfit=130;
extern double StopLoss = 60;
extern double Lots=1;
extern double TrailingStop=30;
extern int ShortEma = 10;
extern int LongEma = 80;
extern bool ExitOnCross = true;
extern int SignalCandle = 0;
extern int MagicNumber = 12345;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
int FreshCross ()
{
double SEma, LEma,SEmaP, LEmaP;
SEma = iMA(NULL,30,ShortEma,0,MODE_EMA,PRICE_CLOSE,SignalCandle);
LEma = iMA(NULL,30,LongEma,0,MODE_EMA,PRICE_CLOSE,SignalCandle);
SEmaP = iMA(NULL,30,ShortEma,0,MODE_EMA,PRICE_CLOSE,SignalCandle+1);
LEmaP = iMA(NULL,30,LongEma,0,MODE_EMA,PRICE_CLOSE,SignalCandle+1);
//Don't work in the first load, wait for the first cross!
if(SEma>LEma && SEmaP < LEmaP) return(1); //up
if(SEma<LEma && SEmaP > LEmaP) return(2); //down
return (0); //not changed
}
//+------------------------------------------------------------------+
//| Check Open Position Controls |
//+------------------------------------------------------------------+
int CheckOpenTrades()
{
int cnt;
int NumTrades; // Number of buy and sell trades in this symbol
NumTrades = 0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
if ( OrderSymbol() != Symbol()) continue;
if ( OrderMagicNumber() != MagicNumber) continue;
if(OrderType() == OP_BUY ) NumTrades++;
if(OrderType() == OP_SELL ) NumTrades++;
}
return (NumTrades);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int cnt, ticket, total;
double TP;
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
/* if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
*/
static int isCrossed = 0;
isCrossed = FreshCross ();
total = CheckOpenTrades();
if(total < 1)
{
if(isCrossed == 1)
{
TP = 0;
if (TakeProfit > 0) TP = Ask + TakeProfit * Point;
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-StopLoss*Point,TP,"EMA_CROSS",MagicNumber,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
}
else Print("Error opening BUY order : ",GetLastError());
return(0);
}
if(isCrossed == 2)
{
TP = 0;
if (TakeProfit > 0) TP = Bid - TakeProfit * Point;
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+StopLoss*Point,TP,"EMA_CROSS",MagicNumber,0,Violet);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
//OrderPrint();
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber() == MagicNumber)
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
/* REMOVED - Trailling stop only close */
if(ExitOnCross && isCrossed == 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Black); // close position
return(0); // exit
}
/**/
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>TrailingStop*Point)
{
if(OrderStopLoss()<Bid-TrailingStop*Point)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*Point,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else // go to short position
{
// should it be closed?
/* REMOVED - Trailling stop only close */
if(ExitOnCross && isCrossed == 1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Black); // close position
return(0); // exit
}
/* */
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(TrailingStop*Point))
{
if((OrderStopLoss()>(Ask+TrailingStop*Point)) || (OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+TrailingStop*Point,OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Comments