ManageTPv2-4_002
Download scriptThis script is designed to automate the management of active trades on a MetaTrader 4 platform. Its primary purpose is to monitor open positions in real-time and automatically execute actions such as taking profits, moving stop-loss levels to secure gains, and closing losing trades based on predefined user parameters.
Core Functionalities
1. Dynamic Take Profit Management The script monitors how many "pips" (a standard unit of price movement) a trade has progressed in your favor. Once a trade reaches a specific profit milestone defined by the user, the script automatically closes that position.
- Incremental Progression: Each time a trade is successfully closed at a target, the script automatically calculates and updates the next target level. This allows for a systematic "ladder" of profit-taking, where the script keeps moving the goalpost forward as you succeed.
2. Automated Stop-Loss Protection (Trailing Logic) One of the key features is the ability to move stop-loss levels dynamically as the market moves in your favor.
- First Stage: Once a trade reaches an initial profit threshold, the script can automatically move the stop-loss to a "safe" point (e.g., moving the loss to break even or locking in a small portion of the profit).
- Second Stage: The script includes a secondary tier for even higher profit targets. If the price continues to move favorably, it can adjust the stop-loss again to lock in significantly larger gains.
3. Risk Management (Hard Stop) The script provides a safety net called a "Max Loss" feature. If a trade moves against your position and reaches a specific amount of loss (defined by the user), the script will immediately intervene and close the trade. This is designed to prevent a single losing trade from accumulating into a larger account drawdown.
Operational Logic
The script operates on a continuous loop, performing the following checks every time the market updates:
- Identification: It scans all open trades to find those matching your specific currency pair and "Magic Number" (a unique ID used to distinguish between different automated strategies).
- Calculation: It constantly calculates the current distance between the current market price and your entry price.
- Execution: Based on that distance, it checks three conditions in order:
- Kill Trade: Is the trade losing too much? (If yes, close immediately).
- Move Stops: Has the trade reached a milestone where we should protect the profit? (If yes, modify the stop-loss).
- Take Profit: Has the trade reached the target to be closed? (If yes, close the trade and set the next goal).
Summary for the User
Essentially, this tool acts as an automated "trade manager." It ensures that once a trade becomes profitable, your gains are protected by moving stop-losses forward automatically, and it ensures that profit targets are hit consistently without requiring you to manually watch the charts every second.
//+------------------------------------------------------------------+
//| TakeProfit.mq4 |
//| Copyright © 2006, Taylor Stockwell |
//| stockwet@yahoo.com |
//| Version: 2.4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Taylor Stockwell"
#property link "stockwet@yahoo.com"
/*
Updates:
11/2/2006:: Fixed bug that caused the sl var to be set to 1 when a pending
order was > than the First_Stop_Target value.
1/23/2007:: Fixed pip calculation. The old way of calculating pips could be
off by 1 pip, resulting in missed TP or move stops. The new
calculation is more accurate.
*/
//=============== VARS external
extern int First_Target = 50;
extern int Target_Increment = 50;
extern double Close_Lots = 0.1;
extern bool Move_Stops = true;
extern int First_Stop_Target = 50;
extern int First_Stop = 1;
extern int Second_Stop_Target = 100;
extern int Second_Stop = 50;
extern bool Use_Max_Loss = false;
extern int Max_Loss = 20;
extern int Magic_Number=0;
//=============== VARS internal
int nextTP;
bool sl;
int range = 5;
int multiplier;
// OrderType == 1 is OP_SELL
//=============== FUNCTION init
int init()
{
sl=0;
nextTP = First_Target;
getMaxLoss();
}
//== end function
//=============== FUNCTION deinit
int deinit()
{
//----
sl=0;
nextTP = First_Target;
//----
return(0);
}
//== end function
//========== FUNCTION Start
int start()
{
//----
getOpenOrders();
getSpread();
//Comment(sl);
//----
return(0);
}
//== end function
//========== FUNCTION getPipValue
double getPipValue(double ord,int dir)
{
double val;
RefreshRates();
if(dir == 1) val=(NormalizeDouble(ord,Digits) - NormalizeDouble(Ask,Digits));
else val=(NormalizeDouble(Bid,Digits) - NormalizeDouble(ord,Digits));
val = val/Point;
return(val);
}
//== end function
int getSpread()
{
int spread=MarketInfo(Symbol(),MODE_SPREAD);
return(spread);
}
int getMaxLoss()
{
int calcMaxLoss;
calcMaxLoss = Max_Loss;
return(calcMaxLoss);
}
//========== FUNCTION getOpenOrders
void getOpenOrders()
{
int nsl, nsd;
string mngMagic;
int totalorders = OrdersTotal();
for(int j=0; j<totalorders;j++)
{
OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderSymbol() == Symbol()&&(Magic_Number==0 || Magic_Number == OrderMagicNumber()))
{
double val=getPipValue(OrderOpenPrice(),OrderType());
//int val = OrderProfit()/(OrderLots()*10);
if(Use_Max_Loss && Max_Loss > 0) killTrade(val,OrderTicket());
if(Move_Stops) checkStops(val,OrderTicket());
takeProfit(val,OrderTicket());
}
if(Magic_Number == 0)
mngMagic = "All "+Symbol()+" trades.";
else
mngMagic = "Trades with magic number = "+Magic_Number;
if(sl==0)
{
nsl = First_Stop_Target;
nsd = First_Stop;
}
else
{
nsl = Second_Stop_Target;
nsd = Second_Stop;
}
//RefreshRates();
//* Comment("Order Open: ",OrderOpenPrice(),
//* "\nPip Count: ", val,
//* "\nNext Stop Target: ",nsl,
//* "\nNext Stop Differential: ", nsd,
//* "\nNext TP: ", nextTP,
//* "\nSL: ",sl,
//* "\nMax Loss: ", getMaxLoss(),
//* "\nManaging: ",mngMagic);
}
}
//========== FUNCTION takeProfit
void takeProfit(int pips, int ticket)
{
if(OrderSelect(ticket, SELECT_BY_TICKET)==true)
{
if(pips >= nextTP && pips < (nextTP + Target_Increment))
{
if(OrderType()==1)
{
if(OrderClose(ticket, Close_Lots, Ask, 3, YellowGreen))
nextTP+=Target_Increment;
else
Print("Error closing order : ",GetLastError());
}
else
{
if(OrderClose(ticket, Close_Lots, Bid, 3, YellowGreen))
nextTP+=Target_Increment;
else
Print("Error closing order : ",GetLastError());
}
}
}
}
//== end function
//========== FUNCTION moveStops
void checkStops(int pips,int ticket)
{
if(sl==0 && pips < Second_Stop_Target)
{
if(pips >= First_Stop_Target && pips < (Second_Stop_Target))
{
moveStops(ticket, First_Stop);
}
}
else if(sl==1 || pips >= Second_Stop_Target)
{
if(pips >= Second_Stop_Target)
{
moveStops(ticket,Second_Stop);
}
}
}
//== end function
//========== FUNCTION moveStops
void moveStops(int ticket,int stopDiff)
{
if(OrderSelect(ticket, SELECT_BY_TICKET)==true)
{
Print("moveStops called ",ticket, " ",stopDiff);
if(OrderType()==1)
{
OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice()-stopDiff*Point, OrderTakeProfit(),0,Plum);
sl=1;
}
else
{
OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice()+stopDiff*Point, OrderTakeProfit(),0,Plum);
sl=1;
}
}
}
//== end function
//========== FUNCTION killTrades
void killTrade(int pips, int ticket)
{
if(OrderSelect(ticket, SELECT_BY_TICKET)==true)
{
if(pips <= -1*getMaxLoss())
{
if(OrderType()==1) OrderClose(ticket,OrderLots(),Ask,3,Red);
else OrderClose(ticket,OrderLots(),Bid,3,Red);
}
}
}
//== end function
Comments