This script is designed to automatically trade currencies in the MetaTrader platform. Here's a breakdown of how it works:
1. Overall Strategy
The script's core goal is to identify potential buying and selling opportunities in the currency market and then automatically place and manage orders (trades) based on those opportunities. It aims to ride trends in the market.
2. Currency Selection
The script trades a set list of currency pairs (like EUR/USD, GBP/JPY, etc.). It cycles through these pairs one by one, spending a short amount of time analyzing each before moving on to the next. This ensures that it considers opportunities across different currency markets.
3. Identifying Trading Direction (Buy or Sell)
The script determines whether to consider buying or selling a particular currency pair using technical indicators, which are mathematical calculations based on historical price data. The specific indicator used for this purpose can be configured, but options include MACD or OSMA. These indicators help the script to estimate the direction of a trend of a price chart.
4. Filtering Trading Opportunities
The script further filters potential trades using another technical indicator, such as the Williams Percent Range (WPR) or a Force Index. This filter aims to confirm that a buy or sell signal is likely to be accurate and reduce the number of false trades.
5. Placing Orders
If both the trading direction indicator and the filter indicator agree, the script will consider placing an order. The script places "pending orders", these are orders to automatically open a trade when the price reaches a specified level. It calculates the price at which the order should be placed based on recent price movements. The script also defines "stop-loss" and "take-profit" levels for each order. Stop-loss is a point where the order will be automatically closed at a loss, this is to limit potential loses of the trade. Take profit is a price point at which the trade will be automatically closed when profitable.
6. Managing Existing Orders
The script also manages existing orders. It checks if the market is moving in a way that justifies keeping an order open. If conditions change (for example, the trading direction changes), the script might cancel a pending order. It also adjusts the stop-loss levels of open trades to protect profits as the market moves in a favorable direction, using a "trailing stop" mechanism.
7. Risk Management
The script includes risk management features to help protect the trading account. These include:
* Lot Size: Limiting the maximum size of trades (number of currency units traded).
* Money Management: The script has a feature to automatically calculate the appropriate trade size based on the account balance and a pre-defined risk tolerance, which is controlled by the MM
parameter.
8. Error Handling
The script includes basic error handling to identify and report any issues that occur during the trading process, such as problems placing orders or connecting to the trading server.
In Summary
The script is a trading robot that automates currency trading based on technical analysis. It identifies potential trades using indicators, filters those trades for higher probability, places and manages orders, and includes risk management features. The goal is to automatically profit from trends in the currency market while minimizing potential losses.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| TSD_MR_Trade_MACD_WPR_0_13.mq4 |
//| Copyright ® 2005 Bob O'Brien / Barcode |
//| TSD v1.2 rewritten to MQL4 and enhanced by Mindaugas |
//| TSD Trade version 0.13 |
//+------------------------------------------------------------------+
#property copyright "Copyright ® 2005 Bob O'Brien / Barcode"
#include <stdlib.mqh>
#define DIRECTION_MACD 1
#define DIRECTION_OSMA 2
#define FILTER_WPR 1
#define FILTER_FORCE 2
// which indicators to use
int DirectionMode = DIRECTION_MACD, FilterMode = FILTER_WPR;
// trading periods
int PeriodDirection = PERIOD_W1, PeriodTrade = PERIOD_D1, PeriodTrailing = PERIOD_H4, CandlesTrailing = 3;
// currency pairs to trade
string pairs[] = { "AUDUSD", "EURCHF", "EURGBP", "EURJPY", "EURUSD", "GBPCHF", "GBPJPY", "GBPUSD",
"USDCAD", "USDCHF", "USDJPY" };
// parameters for MACD and OsMA
int DirectionFastEMA = 5, DirectionSlowEMA = 34, DirectionSignal = 5;
// parameters for iWPR and iForce indicators
int WilliamsP = 24, WilliamsL = -75, WilliamsH = -25;
int ForceP = 2;
int MagicNumber = 2005072001;
int TakeProfit = 100, TrailingStop = 60;
int Slippage = 5, LotsMax = 50;
double Lots = 0.1;
int MM = 0, Leverage = 1, MarginChoke = 200;
string TradeSymbol;
int Pair = 0, SDigits;
datetime LastTrade = 0;
double Spread, SPoint;
//+------------------------------------------------------------------+
int init() { return(0); }
int deinit() { return(0); }
//+------------------------------------------------------------------+
int start() {
int TradesThisSymbol, Direction;
int i, ticket;
bool okSell, okBuy;
double PriceOpen, Buy_Sl, Buy_Tp, LotMM, WilliamsValue;
string ValueComment;
if ( (LastTrade + 15) > CurTime() ) return(0);
Pair = (Pair+1) % ArraySize(pairs);
TradeSymbol = pairs[Pair];
Spread = MarketInfo (TradeSymbol, MODE_ASK) - MarketInfo (TradeSymbol, MODE_BID);
SPoint = MarketInfo (TradeSymbol, MODE_POINT);
SDigits = MarketInfo (TradeSymbol, MODE_DIGITS);
TradesThisSymbol = TotalTradesThisSymbol (TradeSymbol);
Direction = Direction (TradeSymbol, PeriodDirection, DirectionMode);
ValueComment = Filter(TradeSymbol, PeriodTrade, FilterMode, okBuy, okSell);
Comment ("\nSymbol: ", TradeSymbol, "\nMACD Direction: ", Direction, "\n", ValueComment);
/////////////////////////////////////////////////
// Place new order
/////////////////////////////////////////////////
if ( TradesThisSymbol < 1 ) {
LotMM = CalcMM(MM);
if ( LotMM < 0 ) return(0);
ticket = 0;
if ( Direction == 1 && okBuy ) {
MarkTrade();
Print ("TSD BuyStop: ", TradeSymbol, " ", LotMM, " ", CalcOpenBuy(), " ", CalcSlBuy(), " ", CalcTpBuy());
ticket = OrderSend (TradeSymbol, OP_BUYSTOP, LotMM, CalcOpenBuy(), Slippage, CalcSlBuy(), CalcTpBuy(),
"TSD BuyStop", MagicNumber, 0, Blue);
}
if ( Direction == -1 && okSell ) {
MarkTrade();
Print ("TSD SellStop: ", TradeSymbol, " ", LotMM, " ", CalcOpenSell(), " ", CalcSlSell(), " ", CalcTpSell());
ticket = OrderSend (TradeSymbol, OP_SELLSTOP, LotMM, CalcOpenSell(), Slippage, CalcSlSell(), CalcTpSell(),
"TSD SellStop", MagicNumber, 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() != TradeSymbol || OrderMagicNumber() != MagicNumber) continue;
if ( OrderType () == OP_BUYSTOP ) {
if ( Direction != 1 ) {
MarkTrade();
OrderDelete ( OrderTicket() );
return(0);
}
if ( ComparePrices (CalcOpenBuy(), OrderOpenPrice()) != 0 ||
ComparePrices (CalcSlBuy(), OrderStopLoss()) != 0 ) {
MarkTrade();
OrderModify (OrderTicket(), CalcOpenBuy(), CalcSlBuy(), CalcTpBuy(), 0, White);
return(0);
}
}
if ( OrderType () == OP_SELLSTOP ) {
if ( Direction != -1 ) {
MarkTrade();
OrderDelete ( OrderTicket() );
return(0);
}
if ( ComparePrices (CalcOpenSell(), OrderOpenPrice()) != 0 ||
ComparePrices (CalcSlSell(), OrderStopLoss()) != 0 ) {
MarkTrade();
OrderModify (OrderTicket(), CalcOpenSell(), CalcSlSell(), CalcTpSell(), 0, Gold);
return(0);
}
}
} // End of Pending Order Management
/////////////////////////////////////////////////
// Stop Loss Management
/////////////////////////////////////////////////
if ( TrailingStop > 0 ) {
for (i = 0; i < OrdersTotal(); i++) {
if ( OrderSelect (i, SELECT_BY_POS) == false ) continue;
if ( OrderSymbol() != TradeSymbol || OrderMagicNumber() != MagicNumber) continue;
if ( TrailStop (i, TrailingStop) ) return(0);
}
}
return(0);
}
//+------------------------------------------------------------------+
double CalcOpenBuy () { return (dMax (iHigh(TradeSymbol, PeriodTrade, 1) + 1*SPoint + Spread,
MarketInfo(TradeSymbol, MODE_ASK) + 16*SPoint)); }
double CalcOpenSell () { return (dMin (iLow(TradeSymbol, PeriodTrade, 1) - 1*SPoint,
MarketInfo(TradeSymbol, MODE_BID) - 16*SPoint)); }
double CalcSlBuy () { return (iLow (TradeSymbol, PeriodTrade, 1) - 1*SPoint); }
double CalcSlSell () { return (iHigh(TradeSymbol, PeriodTrade, 1) + 1*SPoint + Spread); }
double CalcTpBuy () {
double PriceOpen = CalcOpenBuy(), SL = CalcSlBuy();
if ( TakeProfit == 0 ) return(0);
return (PriceOpen + dMax(TakeProfit*SPoint, (PriceOpen - SL)*2));
}
double CalcTpSell () {
double PriceOpen = CalcOpenSell(), SL = CalcSlSell();
if ( TakeProfit == 0 ) return(0);
return (PriceOpen - dMax(TakeProfit*SPoint, (SL - PriceOpen)*2));
}
//+------------------------------------------------------------------+
bool TrailStop (int i, int TrailingStop) {
double StopLoss;
if ( OrderType() == OP_BUY ) {
if ( MarketInfo (TradeSymbol, MODE_BID) < OrderOpenPrice () ) return;
StopLoss = iLow(TradeSymbol, PeriodTrailing, Lowest (TradeSymbol, PeriodTrailing, MODE_LOW, CandlesTrailing+1, 0)) - 1*SPoint;
StopLoss = dMin (MarketInfo (TradeSymbol, MODE_BID)-TrailingStop*SPoint, StopLoss);
if ( ComparePrices (StopLoss, OrderStopLoss()) == 1 ) {
MarkTrade();
OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, White);
return(true);
}
}
if ( OrderType() == OP_SELL ) {
if ( MarketInfo (TradeSymbol, MODE_ASK) > OrderOpenPrice () ) return;
StopLoss = iHigh(TradeSymbol, PeriodTrailing, Highest (TradeSymbol, PeriodTrailing, MODE_HIGH, CandlesTrailing+1, 0)) + 1*SPoint
+ Spread;
StopLoss = dMax (MarketInfo (TradeSymbol, MODE_ASK)+TrailingStop*SPoint, StopLoss);
if ( ComparePrices (StopLoss, OrderStopLoss()) == -1 ) {
MarkTrade();
OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, Gold);
return(true);
}
}
}
//+------------------------------------------------------------------+
int Direction (string TradeSymbol, int PeriodDirection, int Mode) {
double Previous, Previous2;
if (Mode == DIRECTION_MACD ) {
Previous = iMACD (TradeSymbol, PeriodDirection, DirectionFastEMA, DirectionSlowEMA, DirectionSignal,
PRICE_MEDIAN, MODE_MAIN, 1);
Previous2 = iMACD (TradeSymbol, PeriodDirection, DirectionFastEMA, DirectionSlowEMA, DirectionSignal,
PRICE_MEDIAN, MODE_MAIN, 2);
}
else if (Mode == DIRECTION_OSMA) {
Previous = iOsMA (TradeSymbol, PeriodDirection, DirectionFastEMA, DirectionSlowEMA, DirectionSignal,
PRICE_MEDIAN, 1);
Previous2 = iOsMA (TradeSymbol, PeriodDirection, DirectionFastEMA, DirectionSlowEMA, DirectionSignal,
PRICE_MEDIAN, 2);
}
if ( Previous > Previous2 )
return(1);
if ( Previous < Previous2 )
return(-1);
return(0);
}
//+------------------------------------------------------------------+
string Filter (string TradeSymbol, int PeriodTrade, int Mode, bool &okBuy, bool &okSell) {
double Value;
okBuy = false; okSell = false;
if (Mode == FILTER_WPR) {
Value = iWPR(TradeSymbol, PeriodTrade, WilliamsP, 1);
if (Value < WilliamsH) okBuy = true;
if (Value > WilliamsL) okSell = true;
return ("iWPR: " + DoubleToStr(Value, 2));
}
else if (Mode == FILTER_FORCE) {
Value = iForce (TradeSymbol, PeriodTrade, ForceP, MODE_EMA, PRICE_CLOSE, 1);
if (Value < 0) okBuy = true;
if (Value > 0) okSell = true;
return ("iForce: " + DoubleToStr(Value, 2));
}
}
//+------------------------------------------------------------------+
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 (string TradeSymbol) {
int i, TradesThisSymbol = 0;
for (i = 0; i < OrdersTotal(); i++)
if ( OrderSelect (i, SELECT_BY_POS) )
if ( OrderSymbol() == TradeSymbol && OrderMagicNumber() == MagicNumber )
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);
}
//+------------------------------------------------------------------+
void MarkTrade () {
LastTrade = CurTime();
}
//+------------------------------------------------------------------+
int ComparePrices (double Price1, double Price2) {
double p1 = NormalizeDouble (Price1, SDigits), p2 = NormalizeDouble (Price2, SDigits);
if ( p1 > p2 ) return(1);
if ( p1 < p2 ) return(-1);
return(0);
}
Comments