TSD
Download scriptThis script is an automated trading system designed to manage market entries, order types, and risk management based on two primary technical indicators: the MACD (Moving Average Convergence Divergence) and the Williams %R.
Core Trading Logic
The system operates by looking for specific alignments between different timeframes to determine the trend and potential entry points:
- Trend Identification: The script checks the MACD indicator on a Weekly timeframe to establish the overall market direction. If the MACD is moving upward, it looks for buying opportunities; if it is moving downward, it seeks selling opportunities.
- Entry Confirmation: While the MACD sets the broad direction, the Williams %R indicator (on a Daily timeframe) acts as the specific trigger. The script monitors whether the price is in "oversold" or "overbought" territories to decide when to place an order.
Order Execution Strategy
Unlike systems that enter trades immediately at current prices, this script utilizes Pending Orders (Buy Stops and Sell Stops). This means it places orders at specific price levels that must be reached before a trade is executed:
- Buy Orders: These are placed above recent price highs once the trend and Williams %R conditions align.
- Sell Orders: These are placed below recent price lows once the trend and Williams %R conditions align.
- Dynamic Adjustments: The script continuously monitors these pending orders. If the market trend shifts unexpectedly, it will automatically delete the pending orders to prevent entering a trade against the new momentum. It also modifies the entry prices of these orders based on moving high/low price points.
Risk and Trade Management
The script includes several automated features to protect the account and optimize profit:
- Automated Money Management: The system calculates the appropriate "Lot Size" (trade volume) based on your account balance, leverage, and available margin. It ensures that you do not over-leverage your account based on preset risk levels.
- Dynamic Profit Targets & Stop Losses: Every trade is automatically assigned a Stop Loss and a Take Profit price upon entry. The Take Profit levels are calculated dynamically, ensuring they are placed at a logical distance relative to the risk taken.
- Trailing Stop: For active trades that move into profitability, the script employs a "Trailing Stop" mechanism. This automatically moves the stop loss behind the price as it moves in your favor, aiming to lock in profits while giving the trade room to continue running.
- Trade Limits: The logic ensures that only one trade is open per symbol at any given time, preventing the accumulation of multiple risky positions on the same asset.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| TSD.mq4 |
//| Copyright ® 2005 Bob O'Brien / Barcode |
//| TSD v1.2 rewritten to MQL4 by Mindaugas |
//+------------------------------------------------------------------+
#property copyright "Copyright ® 2005 Bob O'Brien / Barcode"
//---- input parameters
extern int WilliamsP = 24;
extern int WilliamsL = -75;
extern int WilliamsH = -25;
#include <stdlib.mqh>
int Slippage = 5, LotsMax = 50;
int MM = 0, Leverage = 1, MarginChoke = 500;
int TakeProfit = 100, TrailingStop = 60;
double Spread, Lots = 0.1;
int PeriodMacd = PERIOD_W1, PeriodWilliams = PERIOD_D1, PeriodTrailing = PERIOD_H4, CandlesTrailing = 3;
//+------------------------------------------------------------------+
int init() { return(0); }
int deinit() { return(0); }
//+------------------------------------------------------------------+
int start() {
int TradesThisSymbol, Direction;
int i, ticket;
bool WilliamsSell, WilliamsBuy;
double PriceOpen, Buy_Sl, Buy_Tp, LotMM;
double WilliamsValue;
datetime NewBar = 0;
Spread = Ask - Bid;
TradesThisSymbol = TotalTradesThisSymbol ();
Direction = MacdDirection (PeriodMacd);
WilliamsValue = iWPR(NULL, PeriodWilliams, WilliamsP, 1);
Comment ("\nMACD Direction: ", Direction, "\niWPR: ", NormalizeDouble(WilliamsValue, 1));
/////////////////////////////////////////////////
// Process the next bar details
/////////////////////////////////////////////////
if ( NewBar != iTime (NULL, PeriodWilliams, 0) ) {
NewBar = iTime (NULL, PeriodWilliams, 0);
if ( TradesThisSymbol < 1 ) {
LotMM = CalcMM(MM);
if ( LotMM < 0 ) return(0);
WilliamsSell = WilliamsValue > WilliamsL;
WilliamsBuy = WilliamsValue < WilliamsH;
/////////////////////////////////////////////////
// New Orders Management
/////////////////////////////////////////////////
ticket = 0;
if ( Direction == 1 && WilliamsBuy )
ticket = OrderSend (Symbol(), OP_BUYSTOP, LotMM, CalcOpenBuy(), Slippage, CalcSlBuy(), CalcTpBuy(),
"TSD BuyStop", 0, 0, Blue);
if ( Direction == -1 && WilliamsSell )
ticket = OrderSend (Symbol(), OP_SELLSTOP, LotMM, CalcOpenSell(), Slippage, CalcSlSell(), CalcTpSell(),
"TSD SellStop", 0, 0, Red);
if ( ticket == -1 ) ReportError ();
if ( ticket != 0 ) return(0);
} // End of TradesThisSymbol < 1
/////////////////////////////////////////////////
// Pending Order Management
/////////////////////////////////////////////////
for (i = 0; i < OrdersTotal(); i++) {
if ( OrderSelect (i, SELECT_BY_POS) == false ) continue;
if ( OrderSymbol() != Symbol () ) continue;
if ( OrderType () == OP_BUYSTOP ) {
if ( Direction != 1 ) {
OrderDelete ( OrderTicket() );
return(0);
}
if ( iHigh(NULL, PeriodWilliams, 1) < iHigh(NULL, PeriodWilliams, 2) ) {
OrderModify (OrderTicket(), CalcOpenBuy(), CalcSlBuy(), CalcTpBuy(), 0, White);
return(0);
}
}
if ( OrderType () == OP_SELLSTOP ) {
if ( Direction != -1 ) {
OrderDelete ( OrderTicket() );
return(0);
}
if ( iLow(NULL, PeriodWilliams, 1) > iLow(NULL, PeriodWilliams, 2) ) {
OrderModify (OrderTicket(), CalcOpenSell(), CalcSlSell(), CalcTpSell(), 0, Gold);
return(0);
}
}
} // End of Pending Order Management
} // End of Process Next Bar Details
/////////////////////////////////////////////////
// Stop Loss Management
/////////////////////////////////////////////////
if ( TradesThisSymbol > 0 && TrailingStop > 0 ) {
for (i = 0; i < OrdersTotal(); i++) {
if ( OrderSelect (i, SELECT_BY_POS) == false ) continue;
if ( OrderSymbol() != Symbol () ) continue;
TrailStop (i, TrailingStop);
}
}
return(0);
}
//+------------------------------------------------------------------+
double CalcOpenBuy () { return (dMax (iHigh(NULL, PeriodWilliams, 1) + 1*Point + Spread, Ask + 16*Point)); }
double CalcOpenSell () { return (dMin (iLow(NULL, PeriodWilliams, 1) - 1*Point, Bid - 16*Point)); }
double CalcSlBuy () { return (iLow (NULL, PeriodWilliams, 1) - 1*Point); }
double CalcSlSell () { return (iHigh(NULL, PeriodWilliams, 1) + 1*Point + Spread); }
double CalcTpBuy () {
double PriceOpen = CalcOpenBuy(), SL = CalcSlBuy();
return (PriceOpen + dMax(TakeProfit, (PriceOpen - SL)*2));
}
double CalcTpSell () {
double PriceOpen = CalcOpenSell(), SL = CalcSlSell();
return (PriceOpen - dMax(TakeProfit, (SL - PriceOpen)*2));
}
//+------------------------------------------------------------------+
void TrailStop (int i, int TrailingStop) {
double StopLoss;
if ( OrderType() == OP_BUY ) {
if ( Bid < OrderOpenPrice () ) return;
StopLoss = iLow(NULL, PeriodTrailing, Lowest (NULL, PeriodTrailing, MODE_LOW, CandlesTrailing+1, 0)) - 1*Point;
if ( StopLoss > OrderStopLoss() )
OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, White);
}
if ( OrderType() == OP_SELL ) {
if ( Ask < OrderOpenPrice () ) return;
StopLoss = iHigh(NULL, PeriodTrailing, Highest (NULL, PeriodTrailing, MODE_HIGH, CandlesTrailing+1, 0)) + 1*Point
+ Spread;
if ( StopLoss < OrderStopLoss() )
OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, Gold);
}
}
//+------------------------------------------------------------------+
int MacdDirection (int PeriodMacd) {
int Direction = 0;
double MacdPrevious, MacdPrevious2;
MacdPrevious = iMACD (NULL, PeriodMacd, 5, 34, 5, PRICE_MEDIAN, MODE_MAIN, 1);
MacdPrevious2 = iMACD (NULL, PeriodMacd, 5, 34, 5, PRICE_MEDIAN, MODE_MAIN, 2);
if ( MacdPrevious > MacdPrevious2 )
Direction = 1;
if ( MacdPrevious < MacdPrevious2 )
Direction = -1;
return (Direction);
}
//+------------------------------------------------------------------+
double CalcMM (int MM) {
double LotMM;
if ( MM < -1) {
if ( AccountFreeMargin () < 5 ) return(-1);
LotMM = MathFloor (AccountBalance()*Leverage/1000);
if ( LotMM < 1 ) LotMM = 1;
LotMM = LotMM/100;
}
if ( MM == -1 ) {
if ( AccountFreeMargin() < 50 ) return(-1);
LotMM = MathFloor(AccountBalance()*Leverage/10000);
if ( LotMM < 1 ) LotMM = 1;
LotMM = LotMM/10;
}
if ( MM == 0 ) {
if ( AccountFreeMargin() < MarginChoke ) return(-1);
LotMM = Lots;
}
if ( MM > 0 ) {
if ( AccountFreeMargin() < 500 ) return(-1);
LotMM = MathFloor(AccountBalance()*Leverage/100000);
if ( LotMM < 1 ) LotMM = 1;
}
if ( LotMM > LotsMax ) LotMM = LotsMax;
return(LotMM);
}
//+------------------------------------------------------------------+
int TotalTradesThisSymbol () {
int i, TradesThisSymbol = 0;
for (i = 0; i < OrdersTotal(); i++)
if ( OrderSelect (i, SELECT_BY_POS) )
if ( OrderSymbol() == Symbol () )
TradesThisSymbol++;
return (TradesThisSymbol);
}
//+------------------------------------------------------------------+
void ReportError () {
int err = GetLastError();
Print("Error(",err,"): ", ErrorDescription(err));
}
//+------------------------------------------------------------------+
double dMax (double val1, double val2) {
if (val1 > val2) return(val1);
return(val2);
}
//+------------------------------------------------------------------+
double dMin (double val1, double val2) {
if (val1 < val2) return(val1);
return(val2);
}
Profitability Reports
Expected payoff
Average expected payoff across the available backtests for each symbol.
Comments