Author: Copyright � 2005 Bob O'Brien / Barcode
Profit factor:
3.94

This script is designed to automatically place and manage pending orders (Buy Stop and Sell Stop orders) in the MetaTrader 4 platform, aiming to profit from price movements in the financial markets. It uses a combination of two technical indicators ? MACD and Williams Percent Range ? to determine when and where to place these orders. It also manages existing open positions by adjusting their Stop Loss levels to protect profits.

Here's a breakdown of the logic:

  1. Initialization and Input Parameters: The script begins by defining several adjustable settings that users can customize. These settings include the periods for the Williams Percent Range indicator, levels for overbought and oversold conditions according to Williams Percent Range, and settings related to money management, such as risk percentage or fixed lot size per trade. The script also sets parameters for stop loss, take profit and trailing stop.

  2. Market Analysis: The script continuously analyzes the market, looking at the current price and using the MACD and Williams Percent Range indicators.

    • MACD Direction: The script checks the direction of the MACD indicator, comparing its current value to its previous value to determine whether the market is trending upward (Direction = 1) or downward (Direction = -1).
    • Williams Percent Range: It calculates the current value of the Williams Percent Range indicator, which helps identify overbought and oversold conditions.
  3. New Order Placement: If there are no open positions for the current currency pair and a new trading bar has formed:

    • Money Management: The script calculates the appropriate trade size (lot size) based on the user's money management settings, such as a fixed lot size or a percentage of the account balance.
    • Buy Stop Orders: If the MACD indicates an upward trend AND the Williams Percent Range suggests the market is oversold, the script places a Buy Stop order. This is an order to buy the currency pair if the price rises to a specific level (the "open" price), which is calculated based on the high price of the previous period. It also sets a stop loss (to limit potential losses) and a take profit (to automatically close the order when a certain profit level is reached).
    • Sell Stop Orders: Conversely, if the MACD indicates a downward trend AND the Williams Percent Range suggests the market is overbought, the script places a Sell Stop order. This is an order to sell the currency pair if the price falls to a specific level, calculated based on the low price of the previous period. It also sets a stop loss and a take profit.
  4. Pending Order Management: The script manages existing pending orders:

    • Order Cancellation: If the MACD direction changes and no longer aligns with the direction of an existing pending order, the script deletes the pending order. For example, if a Buy Stop order exists but the MACD now indicates a downward trend, the Buy Stop order is cancelled.
    • Order Modification: If certain price conditions are met (determined by comparing high/low prices on the Daily timeframe) the stop loss and take profit of pending orders are modified.
  5. Stop Loss Management (Trailing Stop): For open positions (trades that have already been triggered):

    • Trailing Stop: If the "Trailing Stop" feature is enabled, the script adjusts the stop loss level of open positions as the price moves favorably. For buy orders, the stop loss is moved higher as the price increases, locking in profits. For sell orders, the stop loss is moved lower as the price decreases, locking in profits.
  6. Calculations: The script uses several functions to calculate the optimal levels for order placement and management:

    • CalcOpenBuy() and CalcOpenSell(): Calculates the price at which to place Buy Stop and Sell Stop orders, respectively.
    • CalcSlBuy() and CalcSlSell(): Calculates the Stop Loss price for Buy and Sell orders, respectively.
    • CalcTpBuy() and CalcTpSell(): Calculates the Take Profit price for Buy and Sell orders, respectively.
    • TrailStop(): Implements the trailing stop logic, adjusting the Stop Loss level of existing orders.
    • MacdDirection(): Determines the direction of the MACD indicator.
    • CalcMM(): Calculates the lot size based on the selected money management configuration.

In summary, this script automates the process of finding potential trading opportunities based on two indicators, placing pending orders, and managing those orders (and existing open positions) to protect profits and limit losses. It aims to make trading decisions automatically based on predefined criteria.

Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Orders Execution
Checks for the total of open orders
Indicators Used
Larry William percent range indicator
8 Views
0 Downloads
0 Favorites
TSD_MT4_MR
/*-----------------------------+
|			       |
| Shared by www.Aptrafx.com    |
|			       |
+------------------------------*/

//+------------------------------------------------------------------+
//|                                                   TSD_MT4_MR.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) &&
                 ( !CompareDoubles (CalcSlBuy(), OrderStopLoss()) ||
                   !CompareDoubles (CalcTpBuy(), OrderTakeProfit()) ) ) {
        		   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) &&
                 ( !CompareDoubles (CalcSlSell(), OrderStopLoss()) ||
                   !CompareDoubles (CalcTpSell(), OrderTakeProfit()) ) ) {
        		   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*Point, (PriceOpen - SL)*2));
}
double CalcTpSell  () {
   double PriceOpen = CalcOpenSell(), SL = CalcSlSell();
   return (PriceOpen - dMax(TakeProfit*Point, (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

EUR/USD Jan 2025 - Jul 2025
1.43
Total Trades 26
Won Trades 6
Lost trades 20
Win Rate 23.08 %
Expected payoff 8.84
Gross Profit 765.20
Gross Loss -535.40
Total Net Profit 229.80
-100%
-50%
0%
50%
100%
AUD/USD Jan 2025 - Jul 2025
0.42
Total Trades 24
Won Trades 8
Lost trades 16
Win Rate 33.33 %
Expected payoff -14.01
Gross Profit 241.30
Gross Loss -577.60
Total Net Profit -336.30
-100%
-50%
0%
50%
100%
USD/CAD Oct 2024 - Jan 2025
0.84
Total Trades 10
Won Trades 4
Lost trades 6
Win Rate 40.00 %
Expected payoff -1.34
Gross Profit 68.05
Gross Loss -81.44
Total Net Profit -13.39
-100%
-50%
0%
50%
100%
AUD/USD Oct 2024 - Jan 2025
13.08
Total Trades 3
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff 79.30
Gross Profit 257.60
Gross Loss -19.70
Total Net Profit 237.90
-100%
-50%
0%
50%
100%

Comments