TrailingStopEA
Download scriptThis script is designed to automate the management of your trading positions by dynamically adjusting your stop-loss levels. Its primary goal is to lock in profits as the market moves in your favor while providing options for account-wide risk management.
Here is a breakdown of how the logic works:
Core Functionalities
1. Trailing Stop Loss (The Primary Logic) The script monitors your open trades and "trails" the stop-loss price.
- For Buy Positions: As the market price increases, the script moves the stop-loss upward at a set distance behind the current price. This ensures that if the market suddenly reverses, you keep the profit gained during the move up.
- For Sell Positions: As the market price decreases, the script moves the stop-loss downward at a set distance below the current price.
- Movement Rules: It includes a "Step" logic, meaning it won't move the stop-loss for every tiny price tick; it only updates when the price has moved enough to justify a new stop-loss position.
2. Scope of Operation (Chart vs. Account) You can choose how the script behaves based on your trading style:
- Chart Specific: By default, the script only manages trades that are associated with the specific chart window where it is running.
- Account Wide (All Positions): If enabled, the script ignores which chart a trade was opened on and will manage every single open trade across your entire trading account simultaneously.
3. Profit Protection & Filtering The script contains intelligent filters to prevent unnecessary modifications:
- Profit Only: You can configure the script to only begin trailing once a trade has actually moved into profit. This prevents the stop-loss from moving in a way that might prematurely close a trade that is currently in a loss but still has potential.
- Targeted Trailing: It checks if the price distance from your entry meets your minimum requirements before it begins applying the trailing logic.
4. Global Profit Target (The "Hedge" Option) This is a specialized "all-or-nothing" feature. If you set a specific profit target:
- The script will ignore standard trailing movements and instead monitor your total account profit.
- Once your total account profit reaches the target amount, the script will automatically close all open trades instantly.
- This acts as a safety net to secure a "win" for the day or session across your entire portfolio.
5. Visuals and Notifications
- On-Screen Display: The script provides a clean summary on your chart, showing your current profit in dollars, your set target, the number of open trades, and the status of your trailing stop.
- Audio Alerts: It can be configured to play a sound whenever it successfully modifies a stop-loss, providing real-time confirmation that the script is actively protecting your capital.
//+------------------------------------------------------------------+
//| TrailingStop.mq4 |
//| Copyright © 2006, http://www.forex-tsd.com |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright © Steve Wilson - Forex TSD Forum"
#property link "http://www.forex-tsd.com"
//+--------------------------------------------------------------------+
// This trailing stoploss is made of features found in other Experts. |
// 1. Trailing Stop Loss which is chart specific |
// 2. AllPositions - Trailing Stop Loss which is account specific |
// Attach to any chart and it will modify stop loss on all trades. |
// 3. ProfitTrailing - Modify only trades that are in profit |
// 4. Hedge Option - Does not open positions but will close all trades |
// if a specified target is reached on your trading account. |
// Activate it by giving a value to ProfitTarget. Disables stop |
// loss by setting value to 5000 |
//+--------------------------------------------------------------------+
extern bool AllPositions = false; // (True To modify all positions ) False(modify chart positions)
extern bool ProfitTrailing = True; //(To Trail only postions on profit not loss )
extern int TrailingStop=5; // Minimum is 5
extern int ProfitTarget=0; // Setting this value will calculate all open trades and close if profit reached.
extern int TrailingStep = 1;
extern bool UseSound = True;
extern string NameFileSound = "expert.wav";
bool runnable=true;
bool init=true;
bool result;
double pBid, pAsk, pp;
int i=0;
datetime timeprev=0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
if (ProfitTarget>0)
{
TrailingStop=0;
ChartComment();
ClearStops();
CloseAllTrades();
}
if (AllPositions == false){
//+------------------------------------------------------------------+
//| Expert start function - Chart Specific |
//+------------------------------------------------------------------+
// Clean the chart
if (ProfitTarget==0)
CleanChart();
//Trailing Stop
TrailingAlls(TrailingStop);
//Close/Open
if(timeprev==Time[0])
return(0);
timeprev=Time[0];
return(0);
}
else
{
//+------------------------------------------------------------------+
//| Expert Start Function - All Positions |
//+------------------------------------------------------------------+
// Clean the chart
if (ProfitTarget==0)
CleanChart();
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
TrailingPositions();
}
}
return(0);
}
}
void TrailingAlls(int trail)
{
if (trail==0)
return;
double stopcrnt;
double stopcal;
int trade;
int trades=OrdersTotal();
for(trade=0;trade<trades;trade++)
{
OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
if(OrderSymbol()!=Symbol())
continue;
pp = MarketInfo(OrderSymbol(), MODE_POINT);
//Long
if(OrderType()==OP_BUY)
{
pBid = MarketInfo(OrderSymbol(), MODE_BID);
if (!ProfitTrailing || (pBid-OrderOpenPrice())>TrailingStop*pp) {
if (OrderStopLoss()<pBid-(TrailingStop+TrailingStep-1)*pp) {
stopcrnt=OrderStopLoss();
stopcal=Bid-(trail*Point);
if(stopcrnt==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Blue);
}
else
{
if(stopcal>stopcrnt)
{
OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Blue);
}
}
}
return;
}
}//Long
//Shrt
if(OrderType()==OP_SELL)
{
pAsk = MarketInfo(OrderSymbol(), MODE_ASK);
if (!ProfitTrailing || OrderOpenPrice()-pAsk>TrailingStop*pp) {
if (OrderStopLoss()>pAsk+(TrailingStop+TrailingStep-1)*pp || OrderStopLoss()==0) {
stopcrnt=OrderStopLoss();
stopcal=Ask+(trail*Point);
if(stopcrnt==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Red);
}
else
{
if(stopcal<stopcrnt)
{
OrderModify(OrderTicket(),OrderOpenPrice(),stopcal,OrderTakeProfit(),0,Red);
}
}
}
return;
}
}//Shrt
}//for
}
//+------------------------------------------------------------------+
//| Functions for All Positions |
//+------------------------------------------------------------------+
void TrailingPositions() {
// double pBid, pAsk, pp;
pp = MarketInfo(OrderSymbol(), MODE_POINT);
if (OrderType()==OP_BUY) {
pBid = MarketInfo(OrderSymbol(), MODE_BID);
if (!ProfitTrailing || (pBid-OrderOpenPrice())>TrailingStop*pp) {
if (OrderStopLoss()<pBid-(TrailingStop+TrailingStep-1)*pp) {
ModifyStopLoss(pBid-TrailingStop*pp);
return;
}
}
}
if (OrderType()==OP_SELL) {
pAsk = MarketInfo(OrderSymbol(), MODE_ASK);
if (!ProfitTrailing || OrderOpenPrice()-pAsk>TrailingStop*pp) {
if (OrderStopLoss()>pAsk+(TrailingStop+TrailingStep-1)*pp || OrderStopLoss()==0) {
ModifyStopLoss(pAsk+TrailingStop*pp);
return;
}
}
}
}
//+------------------------------------------------------------------+
//| Modify StopLoss |
//+------------------------------------------------------------------+
void ModifyStopLoss(double ldStopLoss) {
bool fm;
fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
if (fm && UseSound) PlaySound(NameFileSound);
}
//+------------------------------------------------------------------+
void ChartComment()
{
string sComment = "";
string sp = "****************************\n";
string NL = "\n";
sComment = NL + sp;
sComment = sComment + "Current Profits (USD) = $" + DoubleToStr(AccountProfit(),2) + NL;
sComment = sComment + "Profit Target (USD) = $" + ProfitTarget + NL;
sComment = sComment + "Open Trades = " + OrdersTotal() + NL;
sComment = sComment + "Stop Loss Disabled = ("+ TrailingStop+")" + NL;
sComment = sComment + NL + sp;
Comment(sComment);
}
void CleanChart()
{
string sComment = "";
string sp = "****************************\n";
string NL = "\n";
sComment = sComment + NL;
sComment = sComment + NL;
sComment = sComment + NL;
sComment = sComment + NL;
sComment = sComment + NL;
sComment = sComment + NL;
sComment = sComment + NL;
Comment(sComment);
}
// Close all open trades when in profit
void CloseAllTrades(){
if (AccountProfit() >= ProfitTarget){
for (i=OrdersTotal()-1;i>=0;i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
if (OrderType()==OP_SELL)result=OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,CLR_NONE);
if(result!=TRUE) Print("LastError = ", GetLastError());
if (OrderType()==OP_BUY)result=OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,CLR_NONE);
if(result!=TRUE) Print("LastError = ", GetLastError());
if (OrderType()==OP_BUYSTOP)result=OrderDelete(OrderTicket());
if(result!=TRUE) Print("LastError = ", GetLastError());
if (OrderType()==OP_SELLSTOP)result=OrderDelete(OrderTicket());
if(result!=TRUE) Print("LastError = ", GetLastError());
}
else Print( "Error when order select ", GetLastError());
}
}
}
// Function to clear all existing Stop Losses
void ClearStops(){
for (int i=0;i<OrdersTotal();i++){
if (OrderSelect(i,SELECT_BY_POS)){
OrderSelect(i,SELECT_BY_POS);
OrderModify(OrderTicket(),OrderOpenPrice(),0,OrderTakeProfit(),OrderExpiration(),Brown);
}
else Print( "Error when clearing Stops ", GetLastError());
}
return(0);
}
Comments