trade_protector-1.0_v1
Download scriptThis software serves as an automated trade assistant designed to manage active positions by dynamically adjusting Stop Loss (SL) levels. Instead of leaving a trade static, the script monitors market price movements and modifies the exit points based on three primary logic layers: Standard Trailing, Proportional Adjustments, and Emergency Escape mechanisms.
Core Management Logic
1. Initial Protection and Basic Trailing When a new trade is opened without an existing Stop Loss, the assistant automatically establishes a baseline safety net. It places a stop at a predefined distance from the current market price. As the trade progresses, it monitors whether to move this "safety net" to lock in gains or protect against sudden reversals.
2. Proportional Profit Protection This is a sophisticated layer that activates once a trade reaches a specific profit milestone (the threshold). Once this goal is met, the script switches from a fixed distance to a proportional calculation.
- The assistant calculates the distance between the entry price and the current market price.
- It then applies a mathematical ratio to that distance to determine a new Stop Loss position.
- This effectively "trails" the stop loss in a way that correlates with your profit growth, ensuring that as the price moves further in your favor, your protected price level moves along with it at a steady pace.
3. Safety Buffer Logic The script includes a protective check to ensure that if the market price returns very close to the original entry point (specifically within a margin defined by the trading spread), the assistant will prioritize moving the Stop Loss to a conservative "trailing" position. This prevents the trade from swinging back into a loss after a significant move in the right direction.
4. The "Escape" Mechanism The script features an optional emergency exit strategy. If a trade moves against your position and hits a specific "drawdown" level (the Escape Level), the assistant can be configured to prioritize closing the trade at a pre-defined minimum profit or loss target. This is designed to "save" a failing trade by exiting it at a controlled point rather than letting it continue to decline.
Operational Features
- Automated Execution: The script continuously scans all open positions and automatically submits modification orders to the broker as price conditions change.
- Detailed Logging: For traders who want to audit the assistant's behavior, the script maintains two separate log files. These records capture every calculation made by the logic, showing exactly why a Stop Loss was moved and what the various price variables were at that specific moment.
- Dynamic Environment Awareness: The script automatically detects the "Spread" (the difference between buy and sell prices) and the broker's "Stop Level" requirements to ensure that all modifications are valid and executable by the server.
// trade assistant - to watch after SL's for your trades
// some ideas and code fragments: "S.Projects" - "cortex.snowcron.com"
/*
Ïîäðîáíî:
http://codebase.mql4.com/6043
http://codebase.mql4.com/ru/6052
Ïåðåâîä:
Äåíèñ Îðëîâ
http://denis-or-love.narod.ru
http://codebase.mql4.com/ru/author/denis_orlov
*/
extern int logging=1;
//logging=1 - åñëè Âû õîòèòå âåñòè ëîã â êàòàëîãå Experts\Files
extern int nTrailingStop=35;
//nTrailingStop [pips] - íà÷àëüíûé òðåéëèíã ñòîï. Îí áóäåò èñïîëüçîâàòüñÿ, ïîêà âàøà òîðãîâëÿ íå äîñòèãíåò ïðèáûëè = nPropSLThreshold
extern int nPropSLThreshold=12;
//nPropSLThreshold [pips] - ïîñëå äîñòèæåíèÿ ýòîé ïðèáûëè áóäåò èñïîëüçîâàòüñÿ ïðîïîðöèîíàëüíûé òðåéëèíã ñòîï
extern double dPropSLRatio=0.35;
//dPropSLRatio [decimal] - Êîýôôèöèåíò ( dPropSLRatio [äåñÿòè÷íîå ÷èñëî] - Êîýôôèöèåíò (PropSL = Ïðèáûëü * Êîýôôèöèåíò - Ñïðýä))
extern int nUseEscape=0;
//nUseEscape [ 1 or 0 ] - ïîêèíóòü íåóäà÷íûå ïîçèöèè, êàê òîëüêî îíè äîñòèãàþò íåêîòîðîé ìèíèìàëüíîé ïðèáûëè
extern int nEscapeLevel=0;
//nEscapeLevel [pips] - ðàçìåð óáûòêà (ïðîñàäêè) ïîñëå êîòîðîãî ìû áû ðåøèëè ïîêèíóòü ïîçèöèþ ñðàçó ïîñëå
//ïîëó÷åíèÿ ïðèáûëè nEscapeTP
extern int nEscapeTP=35;
//nEscapeTP [pips] - óðîâåíü ïðèáûëè â ïóíêòàõ
//(Âû ìîæåòå óñòàíîâèòü â îòðèöàòåëüíîå çíà÷åíèå - òîãäà ýòî áóäåò óðîâåíü óáûòêà,
//äî êîòîðîãî Âû áûëè áû ñ÷àñòëèâû äîáðàòüñÿ è çàêðûòüñÿ, â ñëó÷àå,
//åñëè âàøà òîðãîâëÿ äîñòèãëà âíóøèòåëüíîé ïðîñàäêè).
double dEscapeLevel;
double dStopLoss;
double dTrailingStop;
double dEscapeTP;
double dPropSLThreshold;
double dTakeProfit;
double dTakeProfitMin;
double dTakeProfitMax;
double dTakeProfitT;
int nBars, nSpread, nDigits, nBarsSameTrend, nCloseErr, nOpenErr, i;
double dDeltaPrice, dnBid, dnAsk, dSpread, dStopLevel, dMax, dMin, dMacdDelta, dMacd1, dMacd2;
// double dOldBalance, dNewBalance;
int nTakeProfitMax=100;
extern int nSlip = 2;
int nBarsSinceTrade=0;
string strExpert = "tp-1.0.0";
// ------
int init ()
{
nBars = Bars;
nSpread = MarketInfo(Symbol(), MODE_SPREAD);
dSpread = NormalizeDouble(nSpread * Point,4);
nDigits = MarketInfo(Symbol(), MODE_DIGITS);
dEscapeTP = NormalizeDouble(nEscapeTP * Point,4);
dEscapeLevel = nEscapeLevel * Point;
return(0);
}
// ------
int deinit()
{
return(0);
}
// ------
int start()
{
// ------
// to let MT rest a bit after new bar:
// Sleep(2500);
// RefreshRates();
dnBid=NormalizeDouble(Bid,nDigits);
dnAsk=NormalizeDouble(Ask,nDigits);
ModifyOrders();
// ------
return(0);
}
// ------
void ModifyOrders()
{
double dSl;
double arrSL[4];
double arrTP[4];
dTrailingStop = NormalizeDouble(nTrailingStop * Point,4);
dEscapeTP = NormalizeDouble(nEscapeTP * Point,4);
dPropSLThreshold = nPropSLThreshold * Point;
dSpread = MarketInfo(Symbol(),MODE_SPREAD) * Point;
dStopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;
for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++)
{
OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
if(true) //(OrderMagicNumber() == nMagic)
{
if(OrderType() == OP_BUY)
{
dSl=OrderStopLoss();
if( dSl == 0 )
dSl = dnBid - dTrailingStop;
arrSL[0]=dSl;
arrSL[1]=dSl;
arrSL[2]=dSl;
arrSL[3]=dSl;
LogSL("OP_BUY-check",dSl,arrSL[0],arrSL[1],arrSL[2],arrSL[3]);
// if( Bid > OrderOpenPrice() + dMaSLDelta )
// arrSL[3]=OrderOpenPrice() + dMaSLDelta;
if( dPropSLRatio > 0 )
{
if( Bid > (OrderOpenPrice() + dPropSLThreshold) )
{
dSl = NormalizeDouble( OrderOpenPrice() + dPropSLRatio*(Bid - OrderOpenPrice()) - dSpread,4 );
if(OrderStopLoss() < dSl)
arrSL[1]=dSl;
}
}
if(Bid < OrderOpenPrice() + 4*dSpread )
{
arrSL[2]=dnBid - dTrailingStop;
}
dSl=arrSL[ArrayMaximum(arrSL)];
LogSL("OP_BUY - max",dSl,arrSL[0],arrSL[1],arrSL[2],arrSL[3]);
if( dSl > OrderStopLoss() || OrderStopLoss() == 0 )
{
OrderModify(OrderTicket(), OrderOpenPrice(),
dSl, OrderTakeProfit(), 0, Yellow);
Log("Buy - modify", 8888, 8888, 0, nBarsSameTrend, OrderOpenPrice(), dSl);
}
// Escape buy
//if( dEscape != 0 && dnBid < OrderOpenPrice() - dEscape - 5 * Point )
if( nUseEscape == 1 && dnBid < OrderOpenPrice() - dEscapeLevel - 5 * Point )
{
OrderModify(OrderTicket(), OrderOpenPrice(),
OrderStopLoss(), OrderOpenPrice() + dEscapeTP, 0, Aqua);
Log("Buy - EscapeLevel", 8888, 8888, 0, nBarsSameTrend, OrderOpenPrice(), dSl);
}
} // end OP_BUY
//////////////////////////////////////////////////////////////////////////////////////////////////
if(OrderType() == OP_SELL)
{
dSl=OrderStopLoss();
if( dSl == 0 )
dSl = dnAsk + dTrailingStop;
arrSL[0]=dSl;
arrSL[1]=dSl;
arrSL[2]=dSl;
arrSL[3]=dSl;
nBarsSinceTrade=GlobalVariableGet("tp-100-BarsSinceTrade") + 1;
GlobalVariableSet("tp-100-BarsSinceTrade",nBarsSinceTrade);
//if( nBarsSinceTrade >= 1 && nBarsSinceTrade < 3 )
// if( Ask < OrderOpenPrice() - dMaSLDelta )
// arrSL[3]=OrderOpenPrice() - dMaSLDelta;
if( dPropSLRatio > 0 )
{
if( Ask < (OrderOpenPrice() - dPropSLThreshold) )
{
dSl = NormalizeDouble( OrderOpenPrice() - dPropSLRatio*(OrderOpenPrice() - Ask) + dSpread,4 );
if( dSl < OrderStopLoss() )
arrSL[1]=dSl;
}
}
if( Ask > OrderOpenPrice() - 4*dSpread )
arrSL[2]=dnAsk + dTrailingStop + dSpread;
dSl=arrSL[ArrayMinimum(arrSL)];
//if( dSl == 0 )
// dSl = arrSL[0];
LogSL("OP_SELL - min",dSl,arrSL[0],arrSL[1],arrSL[2],arrSL[3]);
if( dSl < OrderStopLoss() || OrderStopLoss() == 0 )
{
OrderModify(OrderTicket(), OrderOpenPrice(),
dSl, OrderTakeProfit(), 0, Yellow);
Log("Sell - modify", 8888, 8888, 0, nBarsSameTrend, OrderOpenPrice(), dSl);
}
// Escape sell
//if( dEscape != 0 && dnAsk > OrderOpenPrice() + dEscape + 5 * Point )
if( nUseEscape == 1 && dnAsk > OrderOpenPrice() + dEscapeLevel + 5 * Point )
{
OrderModify(OrderTicket(), OrderOpenPrice(),
OrderStopLoss(), OrderOpenPrice() - dEscapeTP, 0, Aqua);
Log("Buy - EscapeLevel", 8888, 8888, 0, nBarsSameTrend, OrderOpenPrice(), dSl);
}
} // End OP_SELL
} //end if(OrderMagicNumber() == nMagic)
} //end for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++)
} // end ModifyOrders()
//////////////////////////////////////////////////////////////////////////////////////////////////
void Log(string msg, double val1, double val2, double val3, double val4, double val5, double val6)
{
if(logging > 0 )
{
int handle;
handle=FileOpen("tp-100-log.txt",FILE_CSV|FILE_READ|FILE_WRITE,';');
if(handle<1)
{
Print("File tp-100-log.txt not found, the last error is ", GetLastError());
return(false);
}
FileSeek(handle, 0, SEEK_END);
//---- add data to the end of file
//FileWrite(handle, Year(), Month(), Day(), Hour(), Minute(), "Bid, Ask ", msg, Bid, Ask, "___", val1, val2, val3, val4, val5, val6);
FileWrite(handle, Year(), Month(), Day(), Hour(), Minute(), msg, Bid, Ask, 8888, "___", val1, val2, "___", val3, val4, "___", val5, val6);
FileClose(handle);
}
}
void LogSL(string msg, double val1, double val2, double val3, double val4, double val5)
{
if(logging > 0 )
{
int handle;
handle=FileOpen("tp-100-log-sl.txt",FILE_CSV|FILE_READ|FILE_WRITE,';');
if(handle<1)
{
Print("File tp-100-log-sl.txt not found, the last error is ", GetLastError());
return(false);
}
FileSeek(handle, 0, SEEK_END);
//---- add data to the end of file
FileWrite(handle, Year(), Month(), Day(), Hour(), Minute(), msg, Bid, Ask, val1, val2, val3, val4, val5);
FileClose(handle);
}
}
Comments