This script functions as an automated trade management assistant designed to monitor active positions and dynamically adjust Stop Loss (SL) levels based on market movement. Instead of setting a "fixed" protection point, it employs several logical layers to help secure profits or minimize losses automatically.
Core Management Logic
1. Initial Protection When a new trade is opened without an existing Stop Loss, the script can automatically apply a predefined initial safety buffer. This ensures that every position has a baseline level of protection from the moment it enters the market.
2. Proportional Profit Protection The tool features a sophisticated "Proportional" logic. Once a trade reaches a specific profit milestone, the script begins to move the Stop Loss based on a percentage of the current profit.
- How it works: As your profit grows, the Stop Loss follows at a set distance (ratio). This allows the protection level to "breathe" with the market—moving further away as you enter deep profit, but staying close enough to lock in a significant portion of those gains if the price suddenly reverses.
3. Standard Trailing Mechanism In addition to proportional logic, the script can perform a standard trailing stop. This moves the protection point by a fixed amount behind the current market price, ensuring that as the price moves in your favor, your "floor" rises along with it.
4. The "Escape" Mechanism This is a specialized safety feature for trades that might be moving against you. If a trade falls into a significant negative position (exceeding a user-defined threshold), the script can trigger an "escape" mode. It will automatically set a target level to close the trade as soon as it reaches a minor profit point, effectively attempting to "break even" or minimize the damage of a bad move quickly.
Operational Features
- Smart Modification: The script constantly compares the current market price against your active orders. It only modifies an order if the new calculated protection level is better than the current one (e.g., it won't move a Stop Loss backwards into a riskier position).
- Execution Precision: It accounts for "Spreads" (the difference between buying and selling prices) and "Stop Levels" (market restrictions) to ensure that any modification requested is valid and will be accepted by the broker.
- Detailed Logging: For transparency, the script can record all its actions—including price checks, calculation results, and modifications—into a dedicated log file. This allows you to review exactly how the assistant behaved during different market conditions.
// trade assistant - to watch after SL's for your trades
// some ideas and code fragments: "S.Projects" - "cortex.snowcron.com"
extern int logging=1;
//logging=1 - if you want logs in Experts\Files directory
extern int nInitialSL=15;
// inital SL
extern int nTrailingStop=35;
//nTrailingStop [pips] - initial trailing stop. It will be used until your trade will reach profit = nPropSLThreshold
extern int nPropSLThreshold=12;
//nPropSLThreshold [pips] - after reaching this profit proportional trailing stop will be used
extern double dPropSLRatio=0.35;
//dPropSLRatio [decimal] - multiplying factor ( PropSL = Profit * dPropSLRatio - Spred )
extern int nUseEscape=0;
//nUseEscape [ 1 or 0 ] - escape misplaced trades as soon as they reach some minimal profit
extern int nEscapeLevel=0;
//nEscapeLevel [pips] - lose size after which we want our trade to terminate
//as soon as it will reach next high
extern int nEscapeTP=35;
//nEscapeTP [pips] - take profit level in pips (you can set to negative value
//- then it will be a lose that you would be happy to get,
//in the case your trade reached some impressive negative pips value)
extern int nSleep=0;
//delay after new bar
extern int nSlip = 2;
//maximum price slip allowed
double dEscapeLevel;
double dInitialSL;
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;
int nBarsSinceTrade=0;
string strExpert;
// ------
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;
strExpert = "tp-1.2.0-"+Symbol()+"-"+Period();
return(0);
}
// ------
int deinit()
{
return(0);
}
// ------
int start()
{
// ------
// to let MT rest a bit after new bar:
Sleep(nSleep*1000);
if(nSleep > 0)
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;
dInitialSL = NormalizeDouble(nInitialSL * Point,4);
for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++)
{
OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol() == Symbol() ) //(OrderMagicNumber() == nMagic)
{
if(OrderType() == OP_BUY)
{
dSl=OrderStopLoss();
if( dSl == 0 )
if( dInitialSL != 0)
dSl = dnAsk - dInitialSL;
ArrayResize(arrSL,5);
ArrayInitialize(arrSL,dSl);
LogSL("OP_BUY-check",dSl,arrSL[0],arrSL[1],arrSL[2],arrSL[3]);
if( dPropSLRatio > 0 )
{
if( Bid >= (OrderOpenPrice() + dPropSLThreshold) )
{
dSl = NormalizeDouble( OrderOpenPrice() + dPropSLRatio*(Bid - OrderOpenPrice()) - dSpread,4 );
if(OrderStopLoss() < dSl)
arrSL[1]=dSl;
}
else
{
if(dTrailingStop != 0)
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", OrderOpenPrice(), dSl, OrderTakeProfit());
}
// 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", OrderOpenPrice(), dSl, OrderTakeProfit());
}
} // end OP_BUY
//////////////////////////////////////////////////////////////////////////////////////////////////
if(OrderType() == OP_SELL)
{
dSl=OrderStopLoss();
if( dSl == 0 )
if( dInitialSL != 0)
dSl = dnBid + dInitialSL;
ArrayResize(arrSL,5);
ArrayInitialize(arrSL,dSl);
LogSL("OP_SELL-check",dSl,arrSL[0],arrSL[1],arrSL[2],arrSL[3]);
if( dPropSLRatio > 0 )
{
if( Ask <= (OrderOpenPrice() - dPropSLThreshold) )
{
dSl = NormalizeDouble(OrderOpenPrice() - dPropSLRatio*(OrderOpenPrice() - Ask) + dSpread,4);
if(OrderStopLoss() > dSl)
arrSL[1]=dSl;
}
else
{
if(dTrailingStop != 0)
arrSL[2]=dnBid + dTrailingStop;
}
}
dSl=arrSL[ArrayMinimum(arrSL)];
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", OrderOpenPrice(), dSl, OrderTakeProfit());
}
// 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", OrderOpenPrice(), dSl, OrderTakeProfit());
}
} // 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)
{
if(logging > 0 )
{
int handle;
handle=FileOpen(strExpert+".log",FILE_CSV|FILE_READ|FILE_WRITE,';');
if(handle<1)
{
//Print("File "+strExpert+"-log.txt not found, the last error is ", GetLastError());
Print("File "+strExpert+"-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, "___", val1, "___", val2, val3);
FileClose(handle);
}
}
void LogSL(string msg, double val1, double val2, double val3, double val4, double val5)
{
if(logging > 1 )
{
int handle;
handle=FileOpen(strExpert+"-sl_log.txt",FILE_CSV|FILE_READ|FILE_WRITE,';');
if(handle<1)
{
Print("File "+strExpert+"-sl_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(), msg, Bid, Ask, val1, val2, val3, val4, val5);
FileClose(handle);
}
}
Comments