The provided code is a trading strategy script written in MQL4, which is used by MetaTrader 4 (MT4) to automate trading. The script handles buy and sell stop orders, trailing stops, and logging for testing purposes.
Key Components:
-
Variables:
TrailingStop
: Defines the trailing stop distance.TakeProfit
: Specifies the take profit level.LastLogTime
,LastOrderOpenTime
,newbar
: Used for timing events like order modifications and logging.
-
Functions:
-
start()
: Main function that executes on each new bar update.- Checks if it's a new bar (
if (newbar != Time[0])
). - Initializes
newbar
to the current time. - Calls various sub-functions for managing stop orders, buy/sell stops, and trailing stops.
- Checks if it's a new bar (
-
buyStop()
: Manages buy stop orders.- Iterates through existing orders.
- Modifies or removes buy stop orders based on market conditions.
-
sellStop()
: Manages sell stop orders.- Similar logic to
buyStop()
, but for sell orders.
- Similar logic to
-
trailingStops()
: Adjusts trailing stops for open positions.- Updates stop loss levels if the price moves favorably by a certain amount (
TrailingStop * Point
).
- Updates stop loss levels if the price moves favorably by a certain amount (
-
-
Order Management:
- Uses
OrderSelect()
to iterate through active orders and check their properties (e.g., type, symbol). - Utilizes
OrderModify()
to adjust order parameters like stop loss and take profit. - Removes orders using
OrderDelete()
when conditions are met.
- Uses
-
Logging for Testing:
- Conditional logging with
IsTesting()
, which is useful during backtesting or testing in a demo account.
- Conditional logging with
Improvements:
-
Code Organization: Consider breaking down the script into smaller, more manageable functions to improve readability.
-
Error Handling: Add error checks after order operations (e.g.,
OrderModify()
) to handle failures gracefully. -
Variable Naming: Use descriptive variable names for better understanding. For example, rename
cnt
toorderIndex
. -
Magic Numbers: Replace hardcoded values like
-1
and1
with named constants or variables for clarity. -
Comments: Ensure comments are clear and provide meaningful explanations of complex logic.
Example Refactoring:
void manageBuyStops() {
int total = OrdersTotal();
for (int orderIndex = 0; orderIndex < total; orderIndex++) {
if (!OrderSelect(orderIndex, SELECT_BY_POS)) continue;
if (OrderSymbol() == Symbol() && OrderType() == OP_BUYSTOP) {
manageBuyStopOrder(OrderTicket(), OrderOpenPrice(), false);
} else if (OrderSymbol() == Symbol() && OrderType() == OP_BUYLIMIT) {
manageBuyStopOrder(OrderTicket(), OrderOpenPrice(), true);
}
}
}
void manageBuyStopOrder(int ticket, double openPrice, bool isLimitOrder) {
if (isLimitOrder && openPrice > Bid) {
OrderDelete(ticket);
} else if (!isLimitOrder && openPrice < Ask) {
OrderDelete(ticket);
}
}
This refactoring improves readability and maintainability by encapsulating logic into smaller functions.
Profitability Reports
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| TSD_TR_0[1].2_midweekswitch.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
/*[[
Name := TSD
Author := Copyright © 2005 Bob O'Brien / Barcode, MT4 code by Jesse Breaker, modified by TR
Link :=
Notes := Based on Alexander Elder's Triple Screen system. To be run on ANY chart timeframe, but assumes that each daily bar starts at 00:00.
Lots := 1
Stop Loss := 0
Take Profit := 100
Trailing Stop := 60
]]*/
//+------------------------------------------------------------------+
//| External Variables |
//+------------------------------------------------------------------+
extern double LotsIfNoMM = 1.0;
extern int TakeProfit = 100;
extern int Stoploss = 0;
extern int TrailingStop = 60;
extern int Slippage=5; // Slippage
extern int MM_Mode=0,MM_Risk=20;
int cnt=0,total=0, prevLots;
double MacdCurrent=0, MacdPrevious=0, MacdPrevious2=0, Direction=0, OsMAPrevious=0, OsMAPrevious2=0, OsMADirection=0;
double DailyDirection=0, HourlyDirection=0;
double newbar=999,LastLogTime=0,PrevDay=0,PrevMonth=0,PrevYear=0,PrevCurtime=0;
double PriceOpen=0,Lots; // Price Open
bool First=True,OperationSuccess;
double TradesThisSymbol=0;
double WilliamsBuy=0, WilliamsSell=0, ForcePos=0, ForceNeg=0, Force=0,NewPrice=0;
double StartMinute1=0,EndMinute1=0,StartMinute2=0,EndMinute2=0,StartMinute3=0,EndMinute3=0;
double StartMinute4=0,EndMinute4=0,StartMinute5=0,EndMinute5=0,StartMinute6=0,EndMinute6=0;
double StartMinute7=0,EndMinute7=0,DummyField=0;
string eta="NA";
double spread=0;
int start()
{
spread=(Ask-Bid)/Point;
spread=((Ask-Bid)/Point)+1;
if (IsTradeAllowed()) {eta="Yes";} else {eta="No"; Print("TSD Experts are disabled");}
if (! IsTesting())
Comment("TSD for MT4 ver beta 0.3 - DO NOT USE WITH REAL MONEY YET", " Expert trading allowed : ", eta,
"\n",
"\n","Weekly MacdPrevious = ",MacdPrevious," Weekly OsMAPrevious = ",OsMAPrevious,
"\n","Weekly MacdPrevious2 = ",MacdPrevious2," Weekly OsMAPrevious2 = ",OsMAPrevious2,
"\n","Weekly Direction = ",Direction," Weekly OsMADirection = ",OsMADirection,
"\n",
"\n","Is Daily Williams Bullish = ",WilliamsBuy,
"\n","Is Daily Williams Bearish = ",WilliamsSell,
"\n",
"\n","Total Orders = ",total,
"\n","Trades this Symbol(",Symbol(),") = ",TradesThisSymbol,
"\n",
"\n","New Bar Time is ",TimeToStr(newbar),
"\n",
"\n","Daily High[1] = ",iHigh(Symbol(),PERIOD_D1, 1),
"\n","Daily High[2] = ",iHigh(Symbol(),PERIOD_D1, 2),
"\n","Daily Low[1] = ",iLow(Symbol(),PERIOD_D1, 1),
"\n","Daily Low[2] = ",iLow(Symbol(),PERIOD_D1, 2),
"\n",
"\n","Current Ask Price + 16 pips = ",Ask+(16*Point),
"\n","Current Bid Price - 16 pips = ",Bid-(16*Point));
if (MM_Mode < 0) {
Lots = MathCeil(AccountBalance()*MM_Risk/10000)/10;
if (Lots > 100) {
Lots = 100;
}
} else {
Lots = LotsIfNoMM;
}
if (MM_Mode > 0)
{
Lots = MathCeil(AccountBalance()*MM_Risk/10000)/10;
//if (Lots<prevLots) Lots=prevLots;
if (Lots > 1)
{
Lots = MathCeil(Lots);
}
if (Lots < 1)
{
Lots = 1;
}
if (Lots > 100)
{
Lots = 100;
}
}
//prevLots=Lots;
/////////////////////////////////////////////////
// Process the next bar details
/////////////////////////////////////////////////
if (newbar != TimeDayOfWeek(CurTime()))
{
newbar = TimeDayOfWeek(CurTime());
//Newbar will be reset to 999 if the once-a-day order operations below fail, to ensure that they are retried on the next tick.
MacdPrevious = iMACD(NULL,10080,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
MacdPrevious2 = iMACD(NULL,10080,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
if (newbar<4) //Modify this to switch to using current week's OSMA on a specific day of the week (0-Sunday,1,2,3,4,5,6)
{
OsMAPrevious = iOsMA(NULL,10080,12,26,9,PRICE_CLOSE,1);
OsMAPrevious2 = iOsMA(NULL,10080,12,26,9,PRICE_CLOSE,2);
}
else
{
OsMAPrevious = iOsMA(NULL,10080,12,26,9,PRICE_CLOSE,0);
OsMAPrevious2 = iOsMA(NULL,10080,12,26,9,PRICE_CLOSE,1);
}
//OsMAPrevious = iCustom(NULL,10080,"OsMAtestclone_0.5",12,26,9,0,1);
//OsMAPrevious2 = iCustom(NULL,10080,"OsMAtestclone_0.5",12,26,9,0,2);
//OsMAPrevious = iCustom(NULL,PERIOD_D1,"OsMA_5_bar_rolling_0.4",12,26,9,0,1);
//OsMAPrevious2 = iCustom(NULL,PERIOD_D1,"OsMA_5_bar_rolling_0.4",12,26,9,0,2);
/*
Force = iForce(NULL,1440,2,MODE_EMA,PRICE_CLOSE,1);
ForcePos = iForce(NULL,1440,2,MODE_EMA,PRICE_CLOSE,1) > 0;
ForceNeg = iForce(NULL,1440,2,MODE_EMA,PRICE_CLOSE,1) < 0;
*/
//Williams 1/1/05 - 6/30/06 Profit $12,996 79% DD $3364 Absolute 0
// WilliamsBuy = iWPR(NULL,1440,24,1) < -25;
// WilliamsSell = iWPR(NULL,1440,24,1) > -75;
//Stochastic 1/1/05 - 6/30/06 Profit $21,374 79% DD $4964 Absolute 0
WilliamsBuy = iStochastic(NULL,1440,5,3,3,MODE_SMA,0,MODE_MAIN,1) < 80;
WilliamsSell = iStochastic(NULL,1440,5,3,3,MODE_SMA,0,MODE_MAIN,1) > 20;
// WilliamsBuy = iForce(NULL,1440,2,MODE_EMA,PRICE_CLOSE,1) > 0;
// WilliamsSell = iForce(NULL,1440,2,MODE_EMA,PRICE_CLOSE,1) < 0;
if (MacdPrevious > MacdPrevious2) Direction = 1;
if (MacdPrevious < MacdPrevious2) Direction = -1;
if (MacdPrevious == MacdPrevious2) Direction = 0;
if (OsMAPrevious > OsMAPrevious2) OsMADirection = 1;
if (OsMAPrevious < OsMAPrevious2) OsMADirection = -1;
if (OsMAPrevious == OsMAPrevious2) OsMADirection = 0;
//Daily
OsMAPrevious = iOsMA(NULL,1440,12,26,9,PRICE_CLOSE,1);
OsMAPrevious2 = iOsMA(NULL,1440,12,26,9,PRICE_CLOSE,2);
if (OsMAPrevious > OsMAPrevious2) DailyDirection = 1;
if (OsMAPrevious < OsMAPrevious2) DailyDirection = -1;
if (OsMAPrevious == OsMAPrevious2) DailyDirection = 0;
//Hourly
OsMAPrevious = iOsMA(NULL,240,12,26,9,PRICE_CLOSE,1);
OsMAPrevious2 = iOsMA(NULL,240,12,26,9,PRICE_CLOSE,2);
if (OsMAPrevious > OsMAPrevious2) HourlyDirection = 1;
if (OsMAPrevious < OsMAPrevious2) HourlyDirection = -1;
if (OsMAPrevious == OsMAPrevious2) HourlyDirection = 0;
/////////////////////////////////////////////////
// Pending Order Management
/////////////////////////////////////////////////
total=OrdersTotal();
TradesThisSymbol=0;
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol())
{
TradesThisSymbol ++;
} // close for if(OrderSymbol()==Symbol())
} // close for for(cnt=0;cnt<total;cnt++)
if(TradesThisSymbol > 0)
{
total=OrdersTotal();
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)
{
if(OsMADirection == -1)
{
OperationSuccess=OrderDelete(OrderTicket());
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for if(Direction == -1)
} // close for if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)
if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP)
{
if(OsMADirection == 1)
{
OperationSuccess=OrderDelete(OrderTicket());
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} //close for if(Direction == 1)
} //close for if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP)
if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)
{
if(iHigh(Symbol(),PERIOD_D1, 1) < iHigh(Symbol(),PERIOD_D1, 2))
{
if(iHigh(Symbol(),PERIOD_D1, 1) > (Ask + 16 * Point))
{
OperationSuccess=OrderModify(OrderTicket(),iHigh(Symbol(),PERIOD_D1, 1) + 1 * Point,iLow(Symbol(),PERIOD_D1, 1) - 1 * Point,iHigh(Symbol(),PERIOD_D1, 1) + 1 * Point + TakeProfit * Point,0,Cyan);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} //close for if(iHigh(Symbol(),PERIOD_D1, 1) > (Ask + 16 * Point))
else
{
OperationSuccess=OrderModify(OrderTicket(),Ask + 16 * Point,iLow(Symbol(),PERIOD_D1, 1) - 1 * Point,Ask + 16 * Point + TakeProfit * Point,0,Cyan);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} //close for else statement
} //close for if(iHigh(Symbol(),PERIOD_D1, 1) < iHigh(Symbol(),PERIOD_D1, 2))
} //close for if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)
if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP)
{
if(iLow(Symbol(),PERIOD_D1, 1) > iLow(Symbol(),PERIOD_D1, 2))
{
if(iLow(Symbol(),PERIOD_D1, 1) < (Bid - 16 * Point))
{
OperationSuccess=OrderModify(OrderTicket(),iLow(Symbol(),PERIOD_D1, 1) - 1 * Point,iHigh(Symbol(),PERIOD_D1, 1) + 1 * Point,iLow(Symbol(),PERIOD_D1, 1) - 1 * Point - TakeProfit * Point,0,Cyan);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for if(iLow(Symbol(),PERIOD_D1, 1) < (Bid - 16 * Point))
else
{
OperationSuccess=OrderModify(OrderTicket(),Bid - 16 * Point,iHigh(Symbol(),PERIOD_D1, 1) + 1 * Point,Bid - 16 * Point - TakeProfit * Point,0,Cyan);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} //close for else statement
} //close for if(iLow(Symbol(),PERIOD_D1, 1) > iLow(Symbol(),PERIOD_D1, 2))
} //close for if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP)
} // close for for(cnt=0;cnt<total;cnt++)
} // close for if(TradesThisSymbol > 0)
/////////////////////////////////////////////////
// NEW Orders to Place
/////////////////////////////////////////////////
total=OrdersTotal();
TradesThisSymbol=0;
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol())
{
TradesThisSymbol ++;
} // close for if(OrderSymbol()==Symbol())
} // close for for(cnt=0;cnt<total;cnt++)
if(TradesThisSymbol < 1)
{
if(OsMADirection == 1 && /*DailyDirection==1 && HourlyDirection==1)*/WilliamsBuy)
{
PriceOpen = iHigh(Symbol(),PERIOD_D1, 1) + spread * Point; // Buy 1 point above high of previous candle
if(PriceOpen > (Ask + 16 * Point)) // Check if buy price is a least 16 points > Ask
{
OperationSuccess=OrderSend(Symbol(),OP_BUYSTOP,Lots,PriceOpen,Slippage,iLow(Symbol(),PERIOD_D1, 1) - 1 * Point,PriceOpen + TakeProfit * Point,"Buy Entry Order placed at "+CurTime(),0,0,Green);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for if(PriceOpen > (Ask + 16 * Point))
else
{
NewPrice = Ask + 16 * Point;
OperationSuccess=OrderSend(Symbol(),OP_BUYSTOP,Lots,NewPrice,Slippage,iLow(Symbol(),PERIOD_D1, 1) - 1 * Point,NewPrice + TakeProfit * Point,"Buy Entry Order placed at "+CurTime(),0,0,Green);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for else statement
} // close for if(Direction == 1 && WilliamsSell)
if(OsMADirection == -1 && /*DailyDirection==-1 && HourlyDirection==1)*/WilliamsSell)
{
PriceOpen = iLow(Symbol(),PERIOD_D1, 1) - 1 * Point;
if(PriceOpen < (Bid - 16 * Point)) // Check if buy price is a least 16 points < Bid
{
OperationSuccess=OrderSend(Symbol(),OP_SELLSTOP,Lots,PriceOpen,Slippage,iHigh(Symbol(),PERIOD_D1, 1) + spread * Point,PriceOpen - TakeProfit * Point,"Sell Entry Order placed at "+CurTime(),0,0,Green);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for if(PriceOpen < (Bid - 16 * Point))
else
{
NewPrice = Bid - 16 * Point;
OperationSuccess=OrderSend(Symbol(),OP_SELLSTOP,Lots,NewPrice,Slippage,iHigh(Symbol(),PERIOD_D1, 1) + spread * Point,NewPrice - TakeProfit * Point,"Sell Entry Order placed at "+CurTime(),0,0,Green);
if (OperationSuccess==FALSE)
{
newbar=999;
return(0);
}
} // close for else statement
} // close for if(Direction == -1 && WilliamsBuy)
} //Close of if(TradesThisSymbol < 1)
} // close for if (newbar != Time[0])
/////////////////////////////////////////////////
// Stop Loss Management
/////////////////////////////////////////////////
total=OrdersTotal();
TradesThisSymbol=0;
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol())
{
TradesThisSymbol ++;
} // close for if(OrderSymbol()==Symbol())
} // close for for(cnt=0;cnt<total;cnt++)
if(TradesThisSymbol > 0)
{
total=OrdersTotal();
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
{
if (IsTesting() && LastLogTime != iTime(NULL,PERIOD_H1,1))
{
LastLogTime=iTime(NULL,PERIOD_H1,1);
OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()+Point*1,0,Cyan);
}
if(Ask-OrderOpenPrice() > (TrailingStop * Point))
{
if(OrderStopLoss() < (Ask - TrailingStop * Point))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask - TrailingStop * Point,Ask + TakeProfit * Point,0,Cyan);
//return(0);
} // close for if(OrderStopLoss() < (Ask - TrailingStop * Point))
} // close for if(Ask-OrderOpenPrice() > (TrailingStop * Point))
} // close for if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)
{
if (IsTesting() && LastLogTime != iTime(NULL,PERIOD_H1,1))
{
LastLogTime=iTime(NULL,PERIOD_H1,1);
OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()-Point*1,0,Cyan);
}
if(OrderOpenPrice() - Bid > (TrailingStop * Point))
{
if(OrderStopLoss() > (Bid + TrailingStop * Point))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid + TrailingStop * Point,Bid - TakeProfit * Point,0,Cyan);
//return(0);
} // close for if(OrderStopLoss() > (Bid + TrailingStop * Point))
} // close for if(OrderOpenPrice() - Bid > (TrailingStop * Point))
//else if (IsTesting()) OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()-Point*1,0,Cyan);
} // close for if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)
} // close for for(cnt=0;cnt<total;cnt++)
} // close for if(TradesThisSymbol > 0)
//return(0);
} // close for start
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---