Envelope 2.11_all_gbpusdm15_v1
Download scriptStrategy Logic Overview: Envelope 2
This document provides a non-technical explanation of the automated trading logic contained within the provided script. The script is designed to manage trades based on price boundaries, time constraints, and risk management rules.
1. Core Technical Indicators
The script relies on two primary visual and mathematical markers:
- Moving Average (MA): A smoothed average of recent price data used primarily as a reference point for safety stops.
- Envelopes: These are "bands" that sit above and below the Moving Average. They represent specific price boundaries. The script monitors the distance between the current market price and these upper and lower bands to determine where to place orders.
2. Trade Entry Logic (The Setup)
The script looks for specific conditions during set trading hours to place "Pending Orders." These are orders that will only be triggered if the price hits a certain level.
- Buy Opportunities: If the current market price is currently positioned between the upper and lower envelope bands, the script places three separate Buy Stop orders.
- These are placed at the Upper Envelope.
- Each order has a different "Take Profit" target (calculated by adding specific distances to the entry price).
- Sell Opportunities: Simultaneously, under the same conditions, the script places three Sell Stop orders.
- These are placed at the Lower Envelope.
- Each order has its own specific "Take Profit" target (calculated by subtracting specific distances from the entry price).
3. Risk and Lot Management
The script includes a sophisticated system to determine how much money to risk on each trade:
- Dynamic Sizing: It calculates the position size based on your account's available margin and a user-defined maximum risk percentage.
- Loss Adaptation: If the account has experienced a string of recent losses, the script includes a "Decrease Factor." This automatically shrinks the lot size for new trades to protect the account from further rapid depletion until a winning trade occurs.
4. Trade Management (Trailing Stops)
Once a trade is active, the script manages it dynamically to lock in profits:
- Trailing Stop Loss: The script monitors the price as it moves in your favor. If the price crosses past certain envelope boundaries, the "Stop Loss" (the price at which you exit if the trade turns bad) is automatically moved to a safer level (either the Moving Average or the opposite Envelope).
- Protection: This ensures that as a winning trade grows, the potential loss is minimized.
5. Time and Expiration Rules
The script enforces strict discipline regarding timing:
- Active Windows: Trades are only initiated during specific hours defined by the user.
- Order Cleanup: Any "Pending Orders" (orders that haven't been triggered yet) that remain active when the closing hour arrives are automatically deleted.
- Status Tracking: The script constantly monitors the status of its six primary order slots to ensure it doesn't over-trade or lose track of open positions.
//+------------------------------------------------------------------+
//| Envelope 2.mq4 |
//| tageiger |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "tageiger"
#property link "http://www.metaquotes.net"
//---- input parameters
extern int Magic = 12000;
extern int EnvelopePeriod =144;
extern int EnvTimeFrame =0; //envelope time frame: 0=chart,60=1hr,240=4hr, etc.
extern int EnvMaMethod =1; //0=sma,1=ema,2=smma,3=lwma.
extern double EnvelopeDeviation =1;
extern int TimeOpen =0;
extern int TimeClose =23;
extern double FirstTP =89.0;
extern double SecondTP =144.0;
extern double ThirdTP =233.0;
extern double Lots =0.1;
extern double MaximumRisk =0;
extern double DecreaseFactor =5;
extern int MaElineTSL =0;//0=iMA trailing stoploss 1=Opposite Envelope TSL
int b1,b2,b3,s1,s2,s3;
double TSL =0;
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double LotsOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
//---- select lot size
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//---- calcuulate number of losses orders without a break
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//---- return lot size
if(lot<0.1) lot=0.1;
return(lot);
}
int start()
{
int p=0;p=EnvelopePeriod;
int etf=0;etf=EnvTimeFrame;
int mam=0;mam=EnvMaMethod;
double d=0;d=EnvelopeDeviation;
double btp1,btp2,btp3,stp1,stp2,stp3;
double bline=0,sline=0,ma=0;
int cnt, ticket, total;
int digit = MarketInfo(Symbol(),MODE_DIGITS);
ma=iMA(NULL,etf,p,0,mam,PRICE_CLOSE,0);
bline=iEnvelopes(NULL,etf,p,mam,0,PRICE_CLOSE,d,MODE_UPPER,0);
sline=iEnvelopes(NULL,etf,p,mam,0,PRICE_CLOSE,d,MODE_LOWER,0);
total=OrdersTotal();
if(OrdersTotal()==0)
{b1=0;b2=0;b3=0;s1=0;s2=0;s3=0;}
if(OrdersTotal()>0)
{
//Print("Total Orders:",OrdersTotal());
//Print(b1," ",b2," ",b3," ",s1," ",s2," ",s3);
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderMagicNumber()==Magic+2)
{b1=OrderTicket(); }
if(OrderMagicNumber()==Magic+4)
{b2=OrderTicket(); }
if(OrderMagicNumber()==Magic+6)
{b3=OrderTicket(); }
if(OrderMagicNumber()==Magic+1)
{s1=OrderTicket(); }
if(OrderMagicNumber()==Magic+3)
{s2=OrderTicket(); }
if(OrderMagicNumber()==Magic+5)
{s3=OrderTicket(); }
}
//Print ("magic=",OrderMagicNumber());
}
if(b1==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
btp1=(NormalizeDouble(bline,digit))+(FirstTP*Point);
ticket=OrderSend(Symbol(),
OP_BUYSTOP,
LotsOptimized(),
(NormalizeDouble(bline,digit)),
0,
(NormalizeDouble(sline,digit)),
btp1,
"",
Magic+2,
TimeClose,
Aqua);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
b1=ticket;
Print(ticket);
}
else Print("Error Opening BuyStop Order: ",GetLastError());
return(0);
}
}
}
}
if(b2==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
btp2=(NormalizeDouble(bline,digit))+(SecondTP*Point);
ticket=OrderSend(Symbol(),
OP_BUYSTOP,
LotsOptimized(),
(NormalizeDouble(bline,digit)),
0,
(NormalizeDouble(sline,digit)),
btp2,
"",
Magic+4,
TimeClose,
Aqua);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
b2=ticket;
Print(ticket);
}
else Print("Error Opening BuyStop Order: ",GetLastError());
return(0);
}
}
}
}
if(b3==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
btp3=(NormalizeDouble(bline,digit))+(ThirdTP*Point);
ticket=OrderSend(Symbol(),
OP_BUYSTOP,
LotsOptimized(),
(NormalizeDouble(bline,digit)),
0,
(NormalizeDouble(sline,digit)),
btp3,
"",
Magic+6,
TimeClose,
Aqua);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
b3=ticket;
Print(ticket);
}
else Print("Error Opening BuyStop Order: ",GetLastError());
return(0);
}
}
}
}
if(s1==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
stp1=NormalizeDouble(sline,digit)-(FirstTP*Point);
ticket=OrderSend(Symbol(),
OP_SELLSTOP,
LotsOptimized(),
(NormalizeDouble(sline,digit)),
0,
(NormalizeDouble(bline,digit)),
stp1,
"",
Magic+1,
TimeClose,
HotPink);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
s1=ticket;
Print(ticket);
}
else Print("Error Opening SellStop Order: ",GetLastError());
return(0);
}
}
}
}
if(s2==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
stp2=NormalizeDouble(sline,digit)-(SecondTP*Point);
ticket=OrderSend(Symbol(),
OP_SELLSTOP,
LotsOptimized(),
(NormalizeDouble(sline,digit)),
0,
(NormalizeDouble(bline,digit)),
stp2,
"",
Magic+3,
TimeClose,
HotPink);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
s2=ticket;
Print(ticket);
}
else Print("Error Opening SellStop Order: ",GetLastError());
return(0);
}
}
}
}
if(s3==0)
{
if(Hour()>TimeOpen && Hour()<TimeClose)
{
if(bline>Close[0] && sline<Close[0])
{
stp3=NormalizeDouble(sline,digit)-(ThirdTP*Point);
ticket=OrderSend(Symbol(),
OP_SELLSTOP,
LotsOptimized(),
(NormalizeDouble(sline,digit)),
0,
(NormalizeDouble(bline,digit)),
stp3,
"",
Magic+5,
TimeClose,
HotPink);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
s3=ticket;
Print(ticket);
}
else Print("Error Opening SellStop Order: ",GetLastError());
return(0);
}
}
}
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==OP_BUY)
{
if(MaElineTSL==0) {TSL=NormalizeDouble(ma,digit); }
if(MaElineTSL==1) {TSL=NormalizeDouble(sline,digit); }
if(Close[0]>OrderOpenPrice())
{
if((Close[0]>sline) && (TSL>OrderStopLoss()))
{
double bsl;bsl=TSL;
OrderModify(OrderTicket(),
OrderOpenPrice(),
bsl,
OrderTakeProfit(),
0,//Order expiration server date/time
Green);
Sleep(10000);
}
}
}
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==OP_SELL)
{
if(MaElineTSL==0) {TSL=NormalizeDouble(ma,digit); }
if(MaElineTSL==1) {TSL=NormalizeDouble(bline,digit); }
if(Close[0]<OrderOpenPrice())
{
if((Close[0]<bline) && (TSL<OrderStopLoss()))
{
double ssl;ssl=TSL;
OrderModify(OrderTicket(),
OrderOpenPrice(),
ssl,
OrderTakeProfit(),
0,//Order expiration server date/time
Red);
Sleep(10000);
}
}
}
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(Hour()==TimeClose && OrderType()==OP_BUYSTOP)
{
OrderDelete(OrderTicket());
if(OrderTicket()==b1) {b1=0; return;}
if(OrderTicket()==b2) {b2=0; return;}
if(OrderTicket()==b3) {b3=0; return;}
}
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(Hour()==TimeClose && OrderType()==OP_SELLSTOP)
{
OrderDelete(OrderTicket());
if(OrderTicket()==s1) {s1=0; return;}
if(OrderTicket()==s2) {s2=0; return;}
if(OrderTicket()==s3) {s3=0; return;}
}
OrderSelect(b1,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {b1=0;}
OrderSelect(b2,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {b2=0;}
OrderSelect(b3,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {b3=0;}
OrderSelect(s1,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {s1=0;}
OrderSelect(s2,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {s2=0;}
OrderSelect(s3,SELECT_BY_TICKET);
if(OrderClosePrice()>0) {s3=0;}
}
}
Profitability Reports
Expected payoff
Average expected payoff across the available backtests for each symbol.
Comments