MakeGrid v197.mq4
MakeGrid v197.mq4
//| MakeGrid193.mq4 |
//| Copyright � 2005, hdb |
//| http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright � 2005, hdb"
#property link "http://www.dubois1.net/hdb"
//#property version "1.93"
// DISCLAIMER ***** IMPORTANT NOTE ***** READ BEFORE USING *****
// This expert advisor can open and close real positions and hence do real trades
and lose real money.
// This is not a 'trading system' but a simple robot that places trades according
to fixed rules.
// The author has no pretentions as to the profitability of this system and does
not suggest the use
// of this EA other than for testing purposes in demo accounts.
// Use of this system is free - but u may not resell it - and is without any
garantee as to its
// suitability for any purpose.
// By using this program you implicitly acknowledge that you understand what it
does and agree that
// the author bears no responsibility for any losses.
// Before using, please also check with your broker that his systems are adapted
for the frequest trades
// associated with this expert.
// 1.8 changes
// made wantLongs and wantShorts into local variables. Previously, if u set UseMACD
to true,
// it did longs and shorts and simply ignored the wantLongs and wantShorts flags.
// Now, these flags are not ignored.
// added a loop to check if there are 'illicit' open orders above or below the EMA
when the limitEMA34
// flag is used. These accumulate over time and are never removed and is due to the
EMA moving.
// removed the switch instruction as they dont seem to work - replaced with if
statements
// made the EMA period variable
//
// 1.9 changes - as per kind suggestions of Gideon
// Added a routine to delete orders and positions if they are older than
keepOpenTimeLimit hours.
// Added OsMA as a possible filter. Acts exactly like MACD.
// Added 4 parameters for MACD or OsMA so that we can optimise
// Also cleaned up the code a bit.
// 1.92 changes by dave
// added function openPOsitions to count the number of open positions
// modified the order logic so that openPOsitions is not > GridMaxOpen
// 1.93 added long term direction indicator
// Added tradeForMinutes - will only trade for this time then stop till EA is
reset.
// 1.94 added Risk Fraction or also know as Money Management. Spider4896~
// 1.95 seperated the BUYS and SELLS to funtion on different Risk Fractions.
Spider4896~
// 1.96 seperated out the GridSize from Buys and Sells and TakeProfit from Buys and
Sells. Spider4896~
// 1.97 cleaned up code
//
// NOTE: **RISKFRACTION: Code line 443 - 444 were designed for InterbankFX
MicroMini Lots on standard accounts.
// If you would like to use it for other Brokers please adjust code
properly.
//
// HINTS: 1.For long term use please keep in mind it will need a large account
balance. Also for long term
// use try to place bigger size lot trades on the interest positive
direction and smaller
// lot trades on the negative interest side of the trade.
// 2.If used for short term use, use on mutiple of major currencies.
// Example: GBPUSD, USDJPY, USDCHF, EURJPY, EURUSD. Close grid once a
profit is made that you decide upon.
// Long exposure on open trades will result in loss of Equity and might
not reach profit.
//
// modified by cori. Using OrderMagicNumber to identify the trades of the grid
extern int uniqueGridMagic = 11111; // Magic number of the trades. must be
unique to identify
// the trades of one grid
extern double LotsBuy = 0.01; // **TO USE SET LOTS YOU MUST REMOVE
RISKFRACTION CODE..LINES 443 - 444
extern double LotsSell = 0.01; // **TO USE SET LOTS YOU MUST REMOVE
RISKFRACTION CODE..LINES 443 - 444
extern double GridSizeBuy = 8; // pips between orders - grid or mesh size
extern double GridSizeSell = 12; // pips between orders - grid or mesh size
extern double GridSteps = 8; // total number of orders to place
extern double TakeProfitBuy = 10; // number of ticks to take profit.
extern double TakeProfitSell = 10; // number of ticks to take profit.
extern double StopLoss = 0; // normal grids dont use stop losses. DO NOT
USE
extern int trailStop = 0; // will trail if > 0 USE ONLY IF YOUR TP IS
VERY HIGH
extern double RiskFractionBuy=0.6; //Buy Trades: what percent of the account
you want to risk Per Trade
extern double RiskFractionSell=0.4; //Sell Trades: what percent of the account
you want to risk Per Trade
extern int BEPips = 0; // will move the stoploss to BE after x pips
of movement
extern int BEx = 20;
extern double UpdateInterval = 1; // update orders every x minutes
extern bool wantLongs = true; // do we want long positions
extern bool wantShorts = true; // do we want short positions
extern bool wantBreakout = true; // do we want longs above price, shorts
below price
extern bool wantCounter = true; // do we want longs below price, shorts
above price
extern bool limitEMA = true; // do we want longs above ema only, shorts
below ema only
extern int EMAperiod = 32; // the length of the EMA.. was previously
fixed at 34
extern double GridMaxOpen = 999; // maximum number of open positions :
implemented in v1.92
extern bool UseMACD = false; // if true, will use macd >0 for longs only,
macd <0 for shorts only
// on crossover, will cancel all pending
orders. Works in conjunction with wantLongs and wantShorts.
extern bool UseOsMA = false; // if true, will use OSMA > 0 for longs
only, OSMA <0 for shorts only. used in same way as MACD.
// If both UseMACD and UseOSMA atr true,
OSMA is taken.
extern bool CloseOpenPositions = false;// if UseMACD, do we also close open
positions with a loss?
extern bool doHouseKeeping = true; // this will remove long orders below the 34
ema and vv if limitEMA flag is true
extern double keepOpenTimeLimit = 0; // in hours - if > 0, all open orders or
positions will be closed after this period. fractions are permitted
extern int emaFast = 5; // parameters for MACD and OSMA
extern int emaSlow = 34; // parameters for MACD and OSMA
extern int signalPeriod = 5; // parameters for MACD and OSMA
extern int timeFrame = 0; // parameters for MACD and OSMA
extern int minFromPrice = 0; // minimum distance from price to place
trades.
extern int tradeForMinutes=0; // will trade for this number of minutes
after being initialised.
// add/readd the EA before news and it will
trade for these minutes then close out all positions at end
extern int gridOffset = 0; // positions are opened at price modulo
GridSize and offset with this parameter.
// used essentially to enter at non round
numbers
// the following flags set bounds on the prices at which orders may be placed
// this code was developed for and is kindly made public by Exc_ite2
extern bool suspendGrid = false; // if set to true, will close all unfilled
Orders
extern bool shutdownGrid = false; // if set to true, will close all orders
and positions.
// Min/Max tracking
double maxOrders;
double maxEquity;
double minEquity;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
#property show_inputs // shows the parameters - thanks Slawa...
//----
GridName = StringConcatenate( "Grid-", Symbol(),"-",uniqueGridMagic );
return(0);
}
//+------------------------------------------------------------------------+
//| tests if there is an open position or order in the region of atRate |
//| will check for longs if checkLongs is true, else will check |
//| for shorts |
//+------------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Delete order after x hours |
//+------------------------------------------------------------------+
void DeleteAfter( double xHours ) // delete pending orders or open positions
after x hours
{
int totalorders = OrdersTotal();
for(int i=totalorders-1;i>=0;i--)
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
// we use iTime so it works in backtesting
if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) ||
(OrderComment() == GridName)) ) // only look if mygrid and symbol...
{
if (( MathAbs(iTime(Symbol(),5,0)-OrderOpenTime()) >= xHours*60*60 ) &&
(iTime(Symbol(),5,0)>0))
{ bool result = false;
//Close opened long position
if ( OrderType() == OP_BUY ) result = OrderClose( OrderTicket(),
OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
//Close opened short position
if ( OrderType() == OP_SELL ) result = OrderClose( OrderTicket(),
OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
//Close pending order
if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
}
}
} // proc DeleteAfter()
//+------------------------------------------------------------------------+
//| cancells all pending orders |
//+------------------------------------------------------------------------+
void CloseAllPendingOrders( )
{
int totalorders = OrdersTotal();
for(int i=totalorders-1;i>=0;i--) // scan all
orders and positions...
{
OrderSelect(i, SELECT_BY_POS);
// modified as per cori. Using OrderMagicNumber to identify the trades of the
grid // hdb added or gridname for compatibility
if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic)
|| (OrderComment() == GridName)) ) // only look if mygrid and symbol...
{
if ( OrderType() > 1 ) bool result = OrderDelete( OrderTicket() );
}
}
return;
}
//+------------------------------------------------------------------------+
//| cancells all pending orders and closes open positions |
//+------------------------------------------------------------------------+
void ClosePendingOrdersAndPositions()
{
int totalorders = OrdersTotal();
for(int i=totalorders-1;i>=0;i--)
{
OrderSelect(i, SELECT_BY_POS);
bool result = false;
// modified by cori. Using OrderMagicNumber to identify the trades of the grid //
hdb added or gridname for compatibility
if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) ||
(OrderComment() == GridName)) ) // only look if mygrid and symbol...
{
//Close Open Orders
if ( OrderType() == OP_SELL ) result = OrderClose( OrderTicket(),
OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
if ( OrderType() == OP_BUY ) result = OrderClose( OrderTicket(),
OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
//Close pending orders
if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
}
}
return;
}
//+------------------------------------------------------------------------+
//| cancells all open orders which fall on the wrong side of the EMA
|
//+------------------------------------------------------------------------+
//+------------------------------------------------------------------------+
//| counts the number of open positions |
//+------------------------------------------------------------------------+
int openPositions( )
{ int op =0;
int totalorders = OrdersTotal();
for(int i=totalorders-1;i>=0;i--) // scan all
orders and positions...
{
OrderSelect(i, SELECT_BY_POS);
if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic)
|| (OrderComment() == GridName)) ) // only look if mygrid and symbol...
{
int type = OrderType();
if ( type == OP_BUY ) {op=op+1;}
if ( type == OP_SELL ) {op=op+1;}
}
}
return(op);
}
//+------------------------------------------------------------------+
//| Trailing stop procedure |
//+------------------------------------------------------------------+
void TrailIt( int byPips ) // based on trailing stop code from MT
site... thanks MT!
{
if (byPips >=5)
{
for (int i = 0; i < OrdersTotal(); i++) {
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) ||
(OrderComment() == GridName)) ) // only look if mygrid and symbol...
{
if (OrderType() == OP_BUY) {
//if (Bid > (OrderValue(cnt,VAL_OPENPRICE) + TrailingStop * Point))
{
// OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet);
// break;
//}
if (Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(),
MODE_POINT)) {
if (OrderStopLoss() < Bid - byPips * MarketInfo(OrderSymbol(),
MODE_POINT)) {
OrderModify(OrderTicket(), OrderOpenPrice(), Bid - byPips *
MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
}
}
} else if (OrderType() == OP_SELL) {
if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(),
MODE_POINT)) {
if ((OrderStopLoss() > Ask + byPips * MarketInfo(OrderSymbol(),
MODE_POINT)) ||
(OrderStopLoss() == 0)) {
OrderModify(OrderTicket(), OrderOpenPrice(),
Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT),
OrderTakeProfit(), Red);
}
}
}
}
}
}
} // proc TrailIt()
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
int i, j, k, k2, ticket, entermode, totalorders;
bool doit;
double point, startrate, startrate2, traderate, temp;
//----
//Basket profit or loss
//CurrentBasket=AccountEquity()-AccountBalance();
//if(CurrentBasket>maxEquity) maxEquity=CurrentBasket;
//if(CurrentBasket<minEquity) minEquity=CurrentBasket;
if ( TakeProfitBuy <= 0 ) //
{ TakeProfitBuy = GridSizeBuy; }
if ( TakeProfitSell <= 0 )
{ TakeProfitSell = GridSizeSell; }
//----
LastUpdate = CurTime();
//double LotsBuy=(MathCeil(AccountBalance()*RiskFractionBuy/5000.0)/100);
//double LotsSell=(MathCeil(AccountBalance()*RiskFractionSell/5000.0)/100);
point = MarketInfo(Symbol(),MODE_POINT);
startrate = ( Ask + point*GridSizeBuy/2 ) / point / GridSizeBuy; // round to
a number of ticks divisible by GridSize
startrate = ( Bid + point*GridSizeSell/2 ) / point / GridSizeSell; // round
to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSizeBuy ;
k2 = startrate2 ;
k2 = k2 * GridSizeSell ;
startrate = k * point - GridSizeBuy*GridSteps/2*point ; // calculate
the lowest entry point
startrate2 = k2 * point - GridSizeSell*GridSteps/2*point ; // calculate
the lowest entry point
double myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0);
int currentOpen = 0;
if ( GridMaxOpen > 0 ) {
currentOpen = openPositions();
if (currentOpen >= GridMaxOpen) {CloseAllPendingOrders(); }
}
Trigger0=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,0);
Trigger1=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,1);
Trigger2=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,2);
}
if( (Trigger0 > 0) && (Trigger1 > 0) && (Trigger2 < 0 )) // cross up
{
CloseAllPendingOrders();
if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
}
if( (Trigger0<0) && (Trigger1<0) && (Trigger2>0)) // cross down
{
CloseAllPendingOrders();
if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
}
myWantLongs = false;
myWantShorts = false;
if( (Trigger0>0) && (Trigger1>0) && (Trigger2>0) && (wantLongs==true) )
// is well above zero
{
myWantLongs = true;
}
if( (Trigger0<0) && (Trigger1<0) && (Trigger2<0) && (wantShorts== true) )
// is well below zero
{
myWantShorts = true;
}
}
int myGridSteps = GridSteps;
if (( GridMaxOpen > 0 ) && (currentOpen >= GridMaxOpen)) {
myGridSteps = 0;
}
for( i=0;i<myGridSteps;i++)
{
startrate = ( Ask + point*GridSizeBuy/2 ) / point / GridSizeBuy; // round
to a number of ticks divisible by GridSize
startrate2 = ( Bid + point*GridSizeSell/2 ) / point / GridSizeSell; //
round to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSizeBuy ;
k2 = startrate2 ;
k2 = k2 * GridSizeSell ;
startrate = k * point - GridSizeBuy*GridSteps/2*point ; // calculate
the lowest entry point
startrate2 = k2 * point - GridSizeSell*GridSteps/2*point ;
traderate = startrate + i*point*GridSizeBuy + gridOffset*point;
traderate = startrate2 + i*point*GridSizeSell + gridOffset*point;
ticket=OrderSend(Symbol(),entermode,LotsBuy,traderate,0,StopLoss,traderate+point*Ta
keProfitBuy,GridName,uniqueGridMagic,0,LightBlue);
}
}
}
if ( myWantShorts && (!limitEMA || traderate < myEMA))
{ if (shortGridCenter > point) {
temp = GridSteps / 2;
k2 = temp;
startrate2 = shortGridCenter - k2 * GridSizeSell * point ;
} else {
startrate2 = ( Bid + point*GridSizeSell/2 ) / point /
GridSizeSell; // round to a number of ticks divisible by GridSize
k2 = startrate2 ;
k2 = k2 * GridSizeSell ;
startrate2 = k2 * point - GridSizeSell*GridSteps/2*point ; //
calculate the lowest entry point
}
traderate = startrate2 + i*point*GridSizeSell + gridOffset*point;
// now test if traderate within limits
doit = true;
if (traderate < shortGridLow) {doit = false;}
if ((traderate > shortGridHigh) && (shortGridHigh > point)) {doit = false;}
ticket=OrderSend(Symbol(),entermode,LotsSell,traderate,0,myStopLoss,traderate-
point*TakeProfitSell,GridName,uniqueGridMagic,0,White);
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+