Trading Strategy Logic Overview
This script is an automated trading robot designed to execute trades based on technical analysis indicators. It uses a combination of momentum signals and trend identification to decide when to enter, manage, and exit market positions.
1. Safety and Pre-Check Requirements
Before the script performs any actions, it conducts three mandatory safety checks:
- Historical Data: It ensures there are at least 100 bars (price candles) available on the chart to provide enough data for calculation.
- Profit Target Validity: It verifies that the user-defined "Take Profit" value is set to a reasonable minimum to prevent errors.
- Account Liquidity: Before opening any new trades, it checks if the account has sufficient free funds (margin) to cover the required position size.
2. Core Technical Indicators
The logic relies on three primary mathematical tools:
- MACD (Moving Average Convergence Divergence): Used to measure momentum and find "crossovers" between two moving averages.
- Signal Line: A smoothed version of the MACD used as a reference point for entry/exit triggers.
- EMA (Exponential Moving Average): Used specifically to identify the overall direction of the market trend.
3. Entry Logic (Opening Trades)
The script will only open one trade at a time and looks for specific conditions to enter "Buy" or "Sell" positions:
Buy Position (Long)
A buy order is triggered when all the following occur simultaneously:
- Momentum Shift: The MACD line crosses above the Signal line while moving upward.
- Trend Confirmation: The current price trend (EMA) is moving higher than its previous value.
- Magnitude Check: The MACD value must exceed a specific minimum threshold to ensure the move has enough strength to be considered significant.
Sell Position (Short)
A sell order is triggered when all the following occur simultaneously:
- Momentum Shift: The MACD line crosses below the Signal line while moving downward.
- Trend Confirmation: The current price trend (EMA) is moving lower than its previous value.
- Magnitude Check: The MACD value must exceed a specific minimum threshold to ensure sufficient selling pressure.
4. Trade Management and Exit Logic
Once a trade is open, the script actively manages it using two methods:
Automatic Exits (Take Profit/Loss)
The script monitors the indicators to close a trade before the price hits the target. If the MACD shows a reversal in momentum (a "cross" in the opposite direction of the trade) and reaches a specific strength level, the script will automatically close the position to protect profits or limit losses.
Trailing Stop
If enabled by the user, the script employs a Trailing Stop mechanism:
- As the price moves in favor of the trade, the "Stop Loss" order is automatically moved forward to "lock in" profits.
- This ensures that if the market suddenly reverses, the position will close at a pre-defined distance from the current price, preserving a portion of the gains made during the move.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| MACD Sample.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
extern double TakeProfit = 50;
extern double Lots = 0.1;
extern double TrailingStop = 30;
extern double MACDOpenLevel=3;
extern double MACDCloseLevel=2;
extern double MATrendPeriod=26;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double MacdCurrent, MacdPrevious, SignalCurrent;
double SignalPrevious, MaCurrent, MaPrevious;
int cnt, ticket, total;
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external
// variables (Lots, StopLoss, TakeProfit,
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
if(Bars<100)
{
Print("bars less than 100");
return(0);
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
// to simplify the coding and speed up access
// data are put into internal variables
MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);
total=OrdersTotal();
if(total<1)
{
// no opened orders identified
if(AccountFreeMargin()<(1000*Lots))
{
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
// check for long position (BUY) possibility
if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious &&
MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,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);
}
// check for short position (SELL) possibility
if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
MacdCurrent>(MACDOpenLevel*Point) && MaCurrent<MaPrevious)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red);
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);
}
// it is important to enter the market correctly,
// but it is more important to exit it correctly...
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
MacdCurrent>(MACDCloseLevel*Point))
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else // go to short position
{
// should it be closed?
if(MacdCurrent<0 && MacdCurrent>SignalCurrent &&
MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point))
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
// check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
// the end.
Comments