This script is designed to automatically trade on the Forex market based on the daily price range of a currency pair.
Here's how it works:
-
Initialization: When the script starts, it sets up certain parameters like the name of the expert advisor, a magic number (used to identify the trades made by this specific script), slippage (the acceptable difference between the requested price and the actual price), trade volume (Lots), trailing stop, Take profit and time shift.
-
Daily Range Calculation: The script calculates the high and low prices of the currency pair for the previous day based on hourly data. The difference between the high and low prices is the "daily range."
-
Trading Hours: The script has specific hours set for trading and it opens the orders just one time per day.
-
Order Placement: Based on the daily range, the script calculates two price levels:
- Buy Stop: A price above the current price where a buy order will be placed if the price reaches that level. This level is calculated by adding a percentage of the daily range to the opening price.
- Sell Stop: A price below the current price where a sell order will be placed if the price reaches that level. This level is calculated by subtracting a percentage of the daily range from the opening price.
-
Stop Loss and Take Profit: For each trade, the script also sets a stop loss (the price at which the trade will automatically close to limit losses) and a take profit (the price at which the trade will automatically close to secure profits). The stop loss is determined by a percentage of the daily range and the take profit is specified as a quantity of pips.
-
Money Management: The script can automatically adjust the trade size (Lots) based on the account balance and a risk percentage to limit potential losses.
-
Trading Days: The script allows you to specify which days of the week it should trade.
-
Order Management: The script also includes features to manage existing trades:
- Trailing Stop: If enabled, the stop loss will automatically adjust as the price moves in a favorable direction, locking in profits.
- Break Even: If enabled, the stop loss will automatically move to the breakeven point of the trade when the trade reaches certain pips in profit.
- Close by time: if enabled, trades will be closed if they are open for a defined time or if they have a certain profit.
-
Order Deletion: The script automatically deletes opposite pending orders when one order is opened.
In essence, this script is designed to automate a strategy of entering trades when the price breaks out of the previous day's range, with built-in mechanisms for managing risk and protecting profits.
//+------------------------------------------------------------------+
//| SimpleDailyRangeBreakExpert_v1.23.mq4 |
//| Copyright © 2007, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#include <stdlib.mqh>
//---- input parameters
extern string Expert_Name = "---- SimpleDailyRangeBreakExpert_v1.23 ----";
extern int Magic =2009;
extern int Slippage = 6;
extern string Main_Parameters = " Trade Volume & Trade Method";
extern double Lots = 1;
extern double TrailingStop = 0; // Trailing Stop Switch
extern double TakeProfit = 0; //
extern int TimeShift = 9;
extern string Data = " Input Data ";
extern double BuyPercent = 20; // Percent from Daily Range for BUY
extern double SellPercent = 30; // Percent from Daily Range for SELL
extern double StopPercent = 190; // Percent from Daily Range for StopLoss
extern int TradePeriod = 6; // Max days in trade
extern double BreakEven = 0; // BreakEven Level in pips
extern double BreakEvenGap = 0; // Pips when BreakEven will be reached
extern string Trade = " Trade Days of Week";
extern int Monday = 1; // Day of the Week for Trade
extern int Tuesday = 1;
extern int Wednesday = 1;
extern int Thursday = 1;
extern int Friday = 1;
extern string MM_Parameters = " MoneyManagement by L.Williams ";
extern bool MM = true; // ÌÌ Switch
extern double MMRisk = 0.15; // Risk Factor
extern double LossMax = 3200; // Maximum Loss by 1 Lot
int i,cnt=0, ticket, mode=0, digit=0, wenum=0,OrderOpenDay, DaysInTrade, Kz;
double high=0,low=0, close=0, open=0, range=0, spread=0, Profit=0;
double smin=0, smax=0, BuyStop=0, SellStop=0, Lotsi=0, rates_h1[][6];
bool BuyInTrade=false, SellInTrade=false;
datetime StartTime, prevwe=0, Today, PrevDay;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
// ---- Money Management
double MoneyManagement ( bool flag, double Lots, double risk, double maxloss)
{
double Lotsi=Lots;
if ( flag ) Lotsi=NormalizeDouble(Lots*AccountFreeMargin()*risk/maxloss,1);
if (Lotsi<0.1) Lotsi=0.1;
return(Lotsi);
}
// Closing of Pending Orders
void PendOrdDel()
{
int total=OrdersTotal();
for (int cnt=total-1;cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS,MODE_TRADES);
if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic )
{
int mode=OrderType();
bool result = false;
switch(mode)
{
case OP_BUYSTOP : {
result = OrderDelete( OrderTicket() );
if(!result)
{
Print("BUYSTOP: OrderDelete failed with error #",GetLastError());
return(0);
}
break;
}
case OP_SELLSTOP : {
result = OrderDelete( OrderTicket() );
if(!result)
{
Print("SELLSTOP: OrderDelete failed with error #",GetLastError());
return(0);
}
break;
}
}
}
}
}
//
void CloseOrdbyTime()
{
int total=OrdersTotal();
for (cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
mode=OrderType();
if ( mode <= OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if (DaysInTrade >= TradePeriod || OrderProfit()>0)
{
if (mode==OP_BUY )
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Yellow);
if (mode==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White);
}
}
}
}
// ----
void TrailStop()
{
for (cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
int mode=OrderType();
if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if (mode==OP_BUY)
{
BuyStop = NormalizeDouble(Bid - TrailingStop*Point, Digits);
if( OrderOpenPrice() < BuyStop || OrderStopLoss() == 0 )
{
if ( BuyStop > NormalizeDouble(OrderStopLoss(),Digits))
{
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),
BuyStop,
OrderTakeProfit(),0,LightGreen);
if( !result )
{
Print("BUY: OrderModify failed with error #",GetLastError());
}
return(0);
}
}
}
// - SELL Orders
if (mode==OP_SELL)
{
SellStop = NormalizeDouble(Ask + Point * TrailingStop,Digits);
if( OrderOpenPrice() > SellStop)
{
if( NormalizeDouble(OrderStopLoss(), Digits) > SellStop || OrderStopLoss() == 0 )
{
result = OrderModify(OrderTicket(), OrderOpenPrice(),
SellStop,
OrderTakeProfit(),0,DarkOrange);
if( !result )
{
Print("SELL: OrderModify failed with error #",GetLastError());
}
return(0);
}
}
}
}
}
}
void SellOrdOpen()
{
double SellPrice = open - range*SellPercent/100.0 - spread;
if (StopPercent > 0) SellStop=SellPrice + StopPercent*range/100.0; else SellStop=0;
if (TakeProfit > 0) Profit = SellPrice - TakeProfit*Point; else Profit=0;
ticket = OrderSend(Symbol(),OP_SELLSTOP,Lotsi,
NormalizeDouble(SellPrice,digit),
Slippage,
NormalizeDouble(SellStop,digit),
Profit,"SELL",Magic,0,Red);
OrderOpenDay = DayOfWeek();
SellInTrade=false;
if(ticket<0)
{
Print("Sell: OrderSend failed with error #",GetLastError());
return(0);
}
}
void BuyOrdOpen()
{
double BuyPrice = open + range*BuyPercent/100.0 + spread;
if (StopPercent > 0) BuyStop = BuyPrice - StopPercent*range/100.0; else BuyStop=0;
if (TakeProfit > 0) Profit = BuyPrice + TakeProfit*Point; else Profit=0;
ticket = OrderSend(Symbol(),OP_BUYSTOP ,Lotsi,
NormalizeDouble(BuyPrice ,digit),
Slippage,
NormalizeDouble(BuyStop ,digit),
Profit,"BUY",Magic,0,Blue);
OrderOpenDay = DayOfWeek();
BuyInTrade=false;
if(ticket<0)
{
Print("Buy: OrderSend failed with error #",GetLastError());
return(0);
}
}
void ExtraOrdDel()
{
int total = OrdersTotal();
for (cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
mode=OrderType();
if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic )
{
if (mode==OP_BUY && !BuyInTrade ) BuyInTrade =true;
if (mode==OP_SELL && !SellInTrade) SellInTrade=true;
if (mode == OP_SELLSTOP && BuyInTrade )
{
bool result = OrderDelete(OrderTicket());
SellInTrade=false;
if(!result)
{
Print("ExtraSELL: OrderDelete failed with error #",GetLastError());
return(0);
}
}
if (mode == OP_BUYSTOP && SellInTrade )
{
result = OrderDelete(OrderTicket());
BuyInTrade=false;
if(!result)
{
Print("ExtraBUY: OrderDelete failed with error #",GetLastError());
return(0);
}
}
}
}
}
// ---- Scan Trades
int ScanTrades()
{
int total = OrdersTotal();
int numords = 0;
for(cnt=0; cnt<total; cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
if(OrderSymbol() == Symbol() && OrderType()>=OP_BUY && OrderMagicNumber() == Magic)
numords++;
}
return(numords);
}
datetime OrderOpenDate()
{
int total = OrdersTotal();
datetime date;
for(cnt=0; cnt<total; cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
if(OrderSymbol() == Symbol() && OrderType()>=OP_BUY && OrderMagicNumber() == Magic)
date = StrToTime(TimeToStr(OrderOpenTime(),TIME_DATE));
}
return(date);
}
void BreakEvenStop()
{
for (cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt, SELECT_BY_POS);
int mode=OrderType();
if ( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if (mode==OP_BUY)
{
if (Bid-OrderOpenPrice() > BreakEven*Point)
{
Kz = MathFloor((Bid-OrderOpenPrice())/(BreakEven*Point));
if (Bid-OrderOpenPrice() > Kz*BreakEven*Point)
{
BuyStop=OrderOpenPrice()+((Kz-1)*BreakEven+BreakEvenGap)*Point;
if ( OrderStopLoss() == 0 ) double StopLoss = OrderOpenPrice(); else StopLoss = OrderStopLoss();
if (BuyStop > StopLoss )
{
OrderModify(OrderTicket(),OrderOpenPrice(),
NormalizeDouble(BuyStop, digit),
OrderTakeProfit(),0,LightBlue);
return(0);
}
}
}
}
if (mode==OP_SELL)
{
if (OrderOpenPrice()-Ask > BreakEven*Point)
{
Kz = MathFloor((OrderOpenPrice()-Ask)/(BreakEven*Point));
if (OrderOpenPrice()-Ask > Kz*BreakEven*Point)
{
SellStop=OrderOpenPrice()-((Kz-1)*BreakEven+BreakEvenGap)*Point;
if ( OrderStopLoss() == 0 ) StopLoss = OrderOpenPrice(); else StopLoss = OrderStopLoss();
if ( SellStop < StopLoss )
{
OrderModify(OrderTicket(),OrderOpenPrice(),
NormalizeDouble(SellStop, digit),
OrderTakeProfit(),0,Orange);
return(0);
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
if(Bars < 1) {Print("Not enough bars for this strategy"); return(0);}
if (BreakEven >= 0 && BreakEven < BreakEvenGap) return(0);
string TimeTrade = "00:00";
StartTime = StrToTime(TimeTrade) + TimeShift*3600;
if(CurTime() >= StartTime && CurTime() <= StartTime+3600)
{
if ( OrderOpenDate() < StrToTime(TimeToStr( StartTime,TIME_DATE)))
{
if( ScanTrades()>0 && !BuyInTrade && !SellInTrade) PendOrdDel();
Today = StrToTime(TimeToStr( StartTime,TIME_DATE));
if (Today != PrevDay )
{ DaysInTrade = DaysInTrade+1;
//Print(" Days=",DaysInTrade,"Today=",TimeToStr(Today,TIME_DATE),"PrevDay=", TimeToStr(PrevDay,TIME_DATE)) ;
}
if( TradePeriod > 0 )CloseOrdbyTime();
}
if(ScanTrades()<1 && Today != PrevDay )
{
spread= MarketInfo(Symbol(),MODE_SPREAD)*Point;
digit = MarketInfo(Symbol(),MODE_DIGITS);
Lotsi = MoneyManagement ( MM, Lots, MMRisk, LossMax);
//if (TrailingStop > 0) InitialStop=true;
ArrayCopyRates(rates_h1, Symbol(), PERIOD_H1);
open = rates_h1[0][1];
high=0; low=10000000;
for (i=24;i>=1;i--)
{
high = MathMax( high, rates_h1[i][3]);
low = MathMin( low , rates_h1[i][2]);
}
range =(high-low);
if ( Monday == 1 ) if(DayOfWeek()==1){BuyOrdOpen(); SellOrdOpen();}
if ( Tuesday == 1 ) if(DayOfWeek()==2){BuyOrdOpen(); SellOrdOpen();}
if ( Wednesday== 1 ) if(DayOfWeek()==3){BuyOrdOpen(); SellOrdOpen();}
if ( Thursday == 1 ) if(DayOfWeek()==4){BuyOrdOpen(); SellOrdOpen();}
if ( Friday == 1 ) if(DayOfWeek()==5){BuyOrdOpen(); SellOrdOpen();}
DaysInTrade = 0;
}
}
ExtraOrdDel();
if (BreakEven > 0) BreakEvenStop();
if (TrailingStop > 0 ) TrailStop();
PrevDay=Today;
return(0);
}//int start
//+------------------------------------------------------------------+
Comments