Envelope 2.11_all
Download scriptTechnical Logic Overview: Envelope 2 Trading Script
This document provides a non-technical explanation of the logic used by the "Envelope 2" MetaTrader script. The script is designed to automate trade entries, risk management, and exit strategies based on price movement relative to specific technical indicators.
1. Core Indicators and Environment
The script relies on three primary visual and mathematical components to make decisions:
- Moving Average (MA): A smoothed average of recent price action used as a reference point.
- Envelopes: These consist of an "Upper Line" and a "Lower Line" calculated around the Moving Average. They act as dynamic boundaries for price movement.
- Price Position: The script constantly checks where the current market price is sitting in relation to these Upper and Lower Envelope lines.
2. Dynamic Risk and Lot Management
Before opening any trades, the script performs a "Smart Sizing" calculation:
- Margin-Based Sizing: It determines how much of the available account balance it can risk on a single trade.
- Loss Protection (Decrease Factor): The script reviews your trading history. If it detects a recent streak of consecutive losses, it automatically reduces the size of the next trade to protect your capital.
3. Trade Entry Logic
The script manages up to six "Pending Orders" (Buy Stops and Sell Stops). These are orders that wait for the price to hit a specific level before being activated.
Buy Orders (Long Positions)
- Condition: The script looks for a scenario where the current price is trapped between the lines (Price is below the Upper Line but above the Lower Line).
- Execution: It places three different Buy Stop orders at the Upper Envelope line.
- Varied Targets: Each of the three buy orders has a different "Take Profit" target (Short, Medium, and Long), allowing for multiple profit-taking levels simultaneously.
Sell Orders (Short Positions)
- Condition: Similar to the Buy logic, it identifies when the price is within the boundaries.
- Execution: It places three Sell Stop orders at the Lower Envelope line.
- Varied Targets: Like the buy orders, these have three different "Take Profit" targets designed to capture different levels of price retracement.
4. Trade Management and Safety Features
Once a trade is activated (triggered by the market), the script manages it actively:
Trailing Stop Loss (TSL)
To protect profits as the market moves in your favor, the script employs a dynamic "Trailing Stop":
- It monitors the price move relative to the Moving Average or the opposite Envelope line (depending on user settings).
- If the price moves significantly into profit, the script automatically moves the "Stop Loss" closer to the current price. This ensures that if the market suddenly reverses, you lock in a portion of your gains.
Time Filters and Expirations
The script respects specific trading hours:
- Active Window: It will only look for new entries during a user-defined time range (e.g., between certain hours of the day).
- Pending Order Cleanup: Any "Pending" orders (orders waiting to be triggered) that have not been activated by the designated closing hour are automatically deleted to prevent them from being triggered by random price spikes during off-hours.
5. Summary of Operation
- Analyze: Check current price vs. Envelopes and check account history for loss streaks.
- Size: Calculate the safest lot size based on current balance and past performance.
- Deploy: Place pending "Buy" and "Sell" orders at the envelope boundaries during allowed hours.
- Protect: Move Stop Losses automatically as prices move in your favor to secure profit.
- Cleanup: Remove unused pending orders at the end of the trading day.
//+------------------------------------------------------------------+
//| Envelope 2.mq4 |
//| tageiger |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "tageiger"
#property link "http://www.metaquotes.net"
//---- input parameters
extern int Magic = 10000;
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.14;
extern double DecreaseFactor =3;
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