Here's a breakdown of how this trading script operates, explained in plain language:
Overall Goal:
The script is designed to automatically trade in the Forex market. It aims to make profits by opening and closing multiple trades, gradually increasing the size of those trades if the market moves against its initial positions. It also uses filters to determine when to open the first trades.
Key Concepts:
-
Currency Pair: The script focuses on trading a single currency pair (e.g., EUR/USD).
-
Magic Number: A unique identifier to ensure the script only manages its own trades and not others.
-
Lots: The size of the trade (volume of currency being traded).
-
Grid Trading: A strategy where multiple orders are placed at predetermined intervals (the "grid") to profit from small price movements.
-
Take Profit (TP): The price level at which a trade automatically closes for a profit.
-
Money Management: A method to adjust the size of trades based on the account balance, aiming to control risk.
-
Indicators: Technical analysis tools (Bollinger Bands, Stochastics, Volume) used to determine when to enter trades.
Here's how the script works, step-by-step:
-
Initialization (Starting Up):
- The script sets up some initial parameters, like the currency pair it will trade, a unique "magic number" to identify its trades, and the number of decimal places used for prices in that currency pair.
-
Order and Profit Calculation:
- The script scans all open trades in the account.
- It counts how many buy and sell trades are currently open that were placed by this script.
- It calculates the total profit from all open trades managed by the script.
-
Account Protection:
- Equity Protection: It checks if the account's current equity (balance + profit/loss from open trades) has dropped too far below the initial balance. If the loss is greater than a pre-defined percentage, the script closes all open trades to prevent further losses.
-
Trading Logic
- Entry Logic:
- The script uses certain criteria to determine the price at which to open the first Buy or Sell trade.
- Bollinger Bands: If enabled, the script checks the relationship between the price and the Bollinger Bands. Buy orders are triggered when the current price is below the lower band and Sell orders are triggered when the current price is above the upper band.
- Stochastic Oscillator: If enabled, the script checks if the stochastic oscillator is below a threshold (oversold) to Buy or above a threshold (overbought) to Sell.
- Volume Filter: If enabled, the script checks if the current and previous volume is less than a set maximum value. This can be used to prevent the opening of trades if volatility is too high.
- Entry Logic:
-
Grid and Money Management:
- If it has no positions opened and all the entry logica are met, it opens a first Buy or Sell trade.
- If there's a trade opened at the current market price and the price moves in the opposite direction, the script opens one ore more trades.
-
Automatic Grid Calculation
- The script can calculate automatically the distance between the orders, the step and the take profit based on the volatility of the market.
-
Exiting all trades:
- The script has a function that is called when a loss limit is reached, this function is called exitalltrades and closes every trade controlled by the script.
In summary: This script is an automated trading system that attempts to profit from small price movements by using a grid trading strategy, risk management, and technical indicators to determine entry points. It continually monitors open trades, adjusting lot sizes, and managing risk based on account balance and predefined parameters.
//+------------------------------------------------------------------+
//| Blessing 2 v5.2 |
//| Copyright © 2007-2009, MQLCoder.com |
//| jta@jtatoday.com |
//| http://www.irxfx.com |
//| fifthelement80@gmail.com |
//| *** Addition Stochastic Indicator option by epmfx |
//| *** AutoCal Timeframe and Period by Bobster |
//| *** Rewritten by TradingSystemForex.com |
//| In no event will authors be liable for any damages whatsoever |
//| Use at your own risk |
//+------------------------------------------------------------------+
#property copyright "Copyright FiFtHeLeMeNt/J Talon LLC © 2007-2009."
#property link "http://www.mqlcoder.com"
extern int magic=1234; // magic number
extern string comment="Blessing"; // comment to display in the trades
extern string moneymanagement="Money Management";
extern int initialbalance=5000; // initial account balance
extern int accounttype=1; // used in money management feature only, 1=standard, 10=micro
extern double lots=0.01; // starting lots if money management is off
extern bool mm=true; // money management
extern int risk=1; // risk percentage of the account for each trade
extern double lotadjustment=1.0; // adjusts mm base lot for large accounts
extern double multiplier=1.4; // multiplier on each level
extern double multiplier2=2; // second multiplier on each level
extern double lotinc=0; // lot increment on each level, very dangerous
extern int lotdigits=2; // 2 for micro lots, 1 for mini
extern bool equityprotection=true; // close all orders when negative float is excessive
extern double floatpercent=50; // percent of portion for max Float level
extern string ordersmanagement="Order Management";
extern bool autogrid=true; // auto calculation of takeProfit and grid size;
extern int atrtimeframe=1440; // auto tp grid timeframe
extern int atrperiod=21; // auto tp grid period
extern double atrfactor1=2;
extern double atrfactor2=2;
extern double atrfactor3=4;
extern double autogridadjust=0.4; // widens/squishes grid on increments/decrements of .1
extern int pipstep1=25; // set 1 grid size
extern int pipstep2=50; // level 2 grid size
extern int pipstep3=100; // level 3 grid size
extern int takeprofit1=50; // set 1 take profit
extern int takeprofit2=100; // level 2 take profit
extern int takeprofit3=200; // level 3 take profit
extern int timegrid=500; // time grid in seconds, to avoid opening of lots of levels in fast market
extern int maxlevels1=4; // level 1 max levels
extern int maxlevels2=4; // level 2 max levels
extern int maxlevels=99; // level 2 max levels (stops placing orders when reaches maxlvl2)
extern int closelevel=12; // close all level, when reaches this level, doesn't wait for TP to be hit
int roundnumber=5; // used to offset entry to round numbers , for example if you set d=5,
// it will place its sell order on 1.5795 instead of 1.5780
extern string entrylogics="Entry Logics";
extern bool bollinger=true; // bollinger bands filter
extern int bbtimeframe=0;
extern int bbperiod=13;
extern double deviation=2.0;
extern double bbdistance=14;
extern int bbmethod=0;
extern int bbprice=1;
extern int bbshift=0;
extern int closeshift=0;
extern bool stochastics=true;
extern int stochtimeframe=0;
extern int kperiod=10; // stochastic parameters
extern int dperiod=2;
extern int slowing=2;
extern int stochmethod=3;
extern int stochprice=1;
extern int overbought=80;
extern int oversold=20;
extern int stochshift=1;
extern bool volume=false;
extern double maxvolume=250;
extern int slippage=999; // tolerance of order slips/requotes for closing
// Internal Parameters Set
bool openedorders=false;
double slip=0;
double riskbalance,riskequity,initialmultirisk,dd,maxdd,maxddpercent;
int decimal=1,trading=1;
int round,count;
// Expert initialization function
int init(){
if(Digits==3 || Digits==5)decimal=10;
return(0);
}
// Expert deinitialization function
int deinit(){
return(0);
}
// Expert start function
int start(){
int i;
int countbuy=0,countsell=0,countbuylimit=0,countselllimit=0,countbuystop=0,countsellstop=0;
double countbuylot=0,countselllot=0,profit=0;
double ma,stddev,bbup,bbulevel,bbdn,bbdlevel,floatingpoint,lots2;
double lastopenprice,lastopenlots,lastopentp,lastopentime,pipstep,tp,entry;
// Calculate Total Profits and Total Orders
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUY)){
countbuy++;
profit=profit+OrderProfit();
countbuylot=countbuylot+OrderLots();
}
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_SELL)){
countsell++;
profit=profit+OrderProfit();
countselllot=countselllot+OrderLots();
}
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUYLIMIT))countbuylimit++;
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_SELLLIMIT))countselllimit++;
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUYSTOP))countbuystop++;
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_SELLSTOP))countsellstop++;
}
// Account Protection
riskbalance=NormalizeDouble(AccountBalance()/risk,2);
riskequity=NormalizeDouble(riskbalance+profit,2);
if(equityprotection){if(riskbalance-riskequity>=(riskbalance*floatpercent/100))exitalltrades(Red,"Equity Stop Loss Reached");}
// Trading with EA Criteria
initialmultirisk=initialbalance/risk;
if(riskbalance<initialmultirisk){return(0);}
// Money Management and Lot size coding
if(mm){
double contracts,factor,lotsize;
contracts=(AccountBalance()/10000)/risk;
factor=multiplier+MathPow(multiplier,2)+MathPow(multiplier,3)+MathPow(multiplier,4)+MathPow(multiplier,5)+MathPow(multiplier,6);
lotsize=lotadjustment*accounttype*(contracts/(1.0+factor));
// Determine Lot size boundries from minimum to maximum
lots=NormalizeDouble(lotsize,lotdigits);
if(lotsize<0.01)lots=0.01;
if(lotsize>100/MathPow(multiplier,6) && accounttype==1)lots=NormalizeDouble(100/MathPow(multiplier,6),lotdigits);
if(lotsize>50/MathPow(multiplier,6) && accounttype==10)lots=NormalizeDouble(50/MathPow(multiplier,6),lotdigits);
}
// ATR to autocalculate the Grid
double grid,atr;
double atrvalue=iATR(NULL,atrtimeframe,atrperiod,0); // Bobster added external variables; default is 1440, 21
if(autogrid==true){
if(Digits==2 || Digits==3)atr=atrvalue*100;
if(Digits==4 || Digits==5)atr=atrvalue*10000;
grid=atr*atrfactor1/10;
pipstep1=grid;
takeprofit1=grid+pipstep1;
pipstep2=takeprofit1;
takeprofit2=(grid+pipstep1)*atrfactor2;
pipstep3=takeprofit2;
takeprofit3=(grid+pipstep1)*atrfactor3;
}
double Balance=AccountBalance();
double Equity=AccountEquity();
dd=Balance-Equity;
if(dd>maxdd)maxdd=dd;
maxddpercent=(maxdd/Balance)*100;
// Blessing Code
if(countsell==0 && countbuy==0 && countbuystop==0 && countbuylimit==0 && countsellstop==0 && countselllimit==0)openedorders=false;
slip=NormalizeDouble((slippage*decimal),0);
if(((countbuy>=closelevel || countsell>=closelevel) && profit>0) || openedorders){
openedorders=true;
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUY || OrderType()==OP_SELL))OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,Lime);
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP))
OrderDelete(OrderTicket(),White);
}
return;
}
round=roundnumber;
if(decimal==10)round=roundnumber*10;
pipstep=pipstep1;
tp=takeprofit1;
if(countbuy>=maxlevels1 || countsell>=maxlevels1){pipstep=pipstep2;tp=takeprofit2;}
if(countbuy>=maxlevels2+maxlevels1 || countsell>=maxlevels2+maxlevels1){pipstep=pipstep3;tp=takeprofit3;}
// Broker Decimal Selection
if(decimal==10){pipstep*=10;tp*=10;}
// Adjust Grid and Normalize Values
pipstep=NormalizeDouble(pipstep*autogridadjust,0);
tp=NormalizeDouble(tp*autogridadjust,0);
// Bollinger Band trade Long/Short
if(bollinger){
ma=iMA(Symbol(),bbtimeframe,bbperiod,0,bbmethod,bbprice,bbshift);
stddev=iStdDev(Symbol(),bbtimeframe,bbperiod,0,bbmethod,bbprice,bbshift);
bbup=ma+(deviation*stddev);
bbdn=ma-(deviation*stddev);
bbulevel=(bbup+(bbdistance*Point));
bbdlevel=(bbdn-(bbdistance*Point));
}
// Trade Selection Logic
if((countbuy==0)){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUYSTOP) && (OrderLots()>lots))OrderDelete(OrderTicket());
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_BUYLIMIT) && (OrderLots()>lots))OrderDelete(OrderTicket());
}
if((bollinger==false || (bollinger && Close[closeshift]<bbdlevel))
&& (stochastics==false || (stochastics && iStochastic(NULL,stochtimeframe,kperiod,dperiod,slowing,stochmethod,stochprice,0,stochshift)<oversold
&& iStochastic(NULL,stochtimeframe,kperiod,dperiod,slowing,stochmethod,stochprice,1,stochshift)<oversold))
&& (volume==false || (volume && Volume[0]<maxvolume && Volume[1]<maxvolume))){
if(countbuystop==0 && countbuy==0){if(tp>=10)OrderSend(Symbol(),OP_BUY,lots,Ask,0,0,Ask+tp*Point,comment,magic,0,Blue);return;}
}
}
if((countsell==0)){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_SELLSTOP) && (OrderLots()>lots))OrderDelete(OrderTicket());
if((OrderMagicNumber()==magic) && (OrderSymbol()==Symbol()) && (OrderType()==OP_SELLLIMIT) && (OrderLots()>lots))OrderDelete(OrderTicket());
}
if((bollinger==false || (bollinger && Close[closeshift]>bbulevel))
&& (stochastics==false || (stochastics && iStochastic(NULL,stochtimeframe,kperiod,dperiod,slowing,stochmethod,stochprice,0,stochshift)>overbought
&& iStochastic(NULL,stochtimeframe,kperiod,dperiod,slowing,stochmethod,stochprice,1,stochshift)>overbought))
&& (volume==false || (volume && Volume[0]<maxvolume && Volume[1]<maxvolume))){
if(countsellstop==0 && countsell==0){if(tp>=10)OrderSend(Symbol(),OP_SELL,lots,Bid,0,0,Bid-tp*Point,comment,magic,0,Red);return;}
}
}
if(countbuy>0){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()!=magic) || (OrderType()!=OP_BUY) || (OrderSymbol()!=Symbol())){continue;}
lastopenprice=OrderOpenPrice();lastopenlots=OrderLots();lastopentp=OrderTakeProfit();lastopentime=OrderOpenTime();
}
if((TimeCurrent()-timegrid>lastopentime) && (countbuy<maxlevels)){
if(lastopenprice>Ask)entry=NormalizeDouble(lastopenprice-(MathRound((lastopenprice-Ask)/Point/pipstep)+1)*pipstep*Point,Digits);
else entry=NormalizeDouble(lastopenprice-pipstep*Point,Digits);
if(lastopenlots<=0.01)lots2=NormalizeDouble(lastopenlots*multiplier2+lotinc,lotdigits);else lots2=NormalizeDouble(lastopenlots*multiplier+lotinc,lotdigits);
if(countbuylimit==0){OrderSend(Symbol(),OP_BUYLIMIT,lots2,entry,0,0,entry+tp*Point,comment,magic);return;}
if(countbuylimit==1){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if(OrderType()==OP_BUYLIMIT && OrderMagicNumber()==magic && (OrderSymbol()==Symbol()) && entry-OrderOpenPrice()>pipstep/2*Point){
OrderModify(OrderTicket(),entry,0,entry+tp*Point,0);
}
}
}
}
for(i=0;i<OrdersTotal();i++){ // Sync TPs
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()!= magic) || (OrderType()!=OP_BUY) || (MathAbs(OrderTakeProfit()-lastopentp)<Point) || (OrderSymbol()!=Symbol())){continue;}
OrderModify(OrderTicket(),OrderOpenPrice(),0,lastopentp,0,Blue);
return;
}
}
if(countsell>0){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()!=magic) || (OrderType()!=OP_SELL) || (OrderSymbol()!=Symbol())){continue;}
lastopenprice=OrderOpenPrice();lastopenlots=OrderLots();lastopentp=OrderTakeProfit();lastopentime=OrderOpenTime();
}
if((TimeCurrent()-timegrid>lastopentime) && (countsell<maxlevels)){
if(Bid>lastopenprice)entry=NormalizeDouble(lastopenprice+(MathRound((-lastopenprice+Bid)/Point/pipstep)+1)*pipstep*Point,Digits);
else entry=NormalizeDouble(lastopenprice+pipstep*Point,Digits);
if(lastopenlots<=0.01)lots2=NormalizeDouble(lastopenlots*multiplier2+lotinc,lotdigits);else lots2=NormalizeDouble(lastopenlots*multiplier+lotinc,lotdigits);
if(countselllimit==0){OrderSend(Symbol(),OP_SELLLIMIT,lots2,entry,0,0,entry-tp*Point,comment,magic);return;}
if(countselllimit==1){
for(i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if(OrderType()==OP_SELLLIMIT && OrderMagicNumber()==magic && (OrderSymbol()==Symbol()) && OrderOpenPrice()-entry>pipstep/2*Point){
OrderModify(OrderTicket(),entry,0,entry-tp*Point,0);
}
}
}
}
for(i=0;i<OrdersTotal();i++){ // Sync TPs
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if((OrderMagicNumber()!=magic) || (OrderType()!=OP_SELL) || (MathAbs(OrderTakeProfit()-lastopentp)<Point) || (OrderSymbol()!=Symbol())){continue;}
OrderModify(OrderTicket(),OrderOpenPrice(),0,lastopentp,0,Red);
return;
}
}
return(0);
}
void exitalltrades(color clr,string reason){
slip=NormalizeDouble((slippage*decimal),0);
bool success;
for(int cnt=OrdersTotal()-1;cnt>=0;cnt--){
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic){
OrderDelete(OrderTicket(),clr);
success=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,clr);
}
}
}
Comments