This script is designed to automatically place a series of buy and sell orders, creating a "grid" or "mesh" of potential trades around the current market price. It's like setting up a fishing net to catch price movements. Here's a breakdown of how it works:
Core Idea:
The script aims to profit from small price fluctuations by placing multiple orders at regular intervals, both above and below the current price. If the price moves in either direction, some of these orders will be triggered, potentially generating profits.
Key Components and Actions:
-
Settings (External Variables): The script starts with a set of customizable settings that control its behavior. These include:
Lots
: The size of each trade.GridSize
: The distance (in pips) between each order in the grid. A pip is a standard unit of measurement in forex trading.GridSteps
: The total number of orders to place in the grid.TakeProfit
: The profit target (in pips) for each trade. When a trade reaches this profit level, it's automatically closed.StopLoss
: A safety net (in pips). If a trade moves against you and reaches this level of loss, it's automatically closed to limit further losses. Many grid strategies don't use stop losses.WantLongs
: Whether to place buy orders (betting the price will go up).WantShorts
: Whether to place sell orders (betting the price will go down).WantBreakout
: Should the script place orders that expect the price to continue in its direction?WantCounter
: Should the script place orders that expect the price to reverse direction?LimitEMA
: This setting limits the placement of orders based on the Exponential Moving Average (EMA), a technical indicator. If enabled, buy orders will only be placed above the EMA, and sell orders below it.EMAperiod
: The length of the Exponential Moving AverageUseMACD
andUseOsMA
: These settings allow the script to use two other technical indicators MACD and OSMA to filter the trades. If enabled, the script will only place buy orders when the MACD or OSMA indicates an upward trend, and sell orders when they indicate a downward trend.CloseOpenPositions
: IfUseMACD
orUseOsMA
are enabled, this setting determines whether the script should also close any existing open positions when the MACD or OSMA signal changes.GridMaxOpen
: Limits the maximum number of open orders and positions.UniqueGridMagic
: Identifies the trades placed by this specific script, allowing it to manage them separately from other trades.TradeForMinutes
: The amount of time this script should trade before stopping.LongGridCenter
,ShortGridCenter
,LongGridLow
,LongGridHigh
,ShortGridLow
,ShortGridHigh
: Settings to set the boundaries for trade placement.ProfitTarget
: A target amount of profit for the script to aim for. Once this profit is reached, the script can close all positions.SuspendGrid
andShutdownGrid
: Used to control the grid. The first cancels all pending orders, the second one closes all orders and positions.
-
Initialization (init() function): This part runs once when the script is first attached to a chart. It sets up a unique name for the grid, making it easier to identify the script's trades.
-
Main Loop (start() function): This is the heart of the script, running repeatedly to check market conditions and manage the grid.
- Time Check: The script only executes its main logic at specific time intervals to avoid excessive calculations and order modifications.
- Price Levels: It calculates the price levels at which to place the orders, based on the
GridSize
,GridSteps
, and current market price. - Order Placement: The script places pending buy and sell orders at the calculated price levels. These orders are "pending" because they only become active trades if the market price reaches those levels.
- Order Management:
- The script checks if there are already orders at the desired price levels to avoid placing duplicate orders.
- It considers the
WantLongs
andWantShorts
settings to determine whether to place buy, sell, or both types of orders. - If EMA filtering is enabled (
LimitEMA
), it only places orders that align with the EMA's direction. - It includes an option to delete orders and positions after a set time.
- It checks if any order is on the wrong side of the EMA
- Technical Indicator Filtering: If
UseMACD
orUseOsMA
are enabled, the script analyzes the MACD or OSMA values to determine whether to place buy or sell orders. If a signal changes, it can cancel all pending orders and, optionally, close existing positions. - Profit Target: The script constantly checks the total profit made. If the
ProfitTarget
is reached, the script can close all positions and stop trading. - Trailing Stop: The script can also implement a trailing stop, which automatically adjusts the stop loss level as the trade moves in your favor, to lock in profits.
- Break Even: The script can move the Stop Loss to Break Even to avoid losing money.
In Simple Terms:
Imagine you're setting up a series of traps to catch fish. The script is like a robot that:
- Calculates where to place the traps (orders) based on the current water level (price) and the desired spacing between them.
- Sets the traps (places pending orders) to catch fish swimming up (buy orders) or down (sell orders).
- Adjusts the traps (modifies orders) based on the water level and other factors.
- Closes the traps (closes orders) when it catches enough fish (reaches profit target) or if the conditions change.
Important Considerations:
- Risk: Grid trading can be risky, as it involves placing multiple orders, which can lead to significant losses if the market moves strongly against you.
- Settings: The profitability of the script depends heavily on the chosen settings, which need to be carefully optimized for the specific currency pair and market conditions.
- Backtesting: It's essential to test the script thoroughly in a demo account or through backtesting before using it with real money.
- Broker: The trader needs to make sure that the Broker can handle the speed this script operates on.
This explanation provides a general understanding of the script's logic. Remember that trading involves risk, and it's crucial to understand the potential consequences before using any automated trading system.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| 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.
//
// 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 Lots = 0.1; //
extern double GridSize = 6; // pips between orders - grid or mesh size
extern double GridSteps = 10; // total number of orders to place
extern double TakeProfit = 10 ; // number of ticks to take profit. normally is = grid size but u can override
extern double StopLoss = 0; // if u want to add a stop loss. normal grids dont use stop losses
extern int trailStop = 0; // will trail if > 0
extern int BEPips = 0; // will move the stoploss to BE after x pips of movement
extern double UpdateInterval = 1; // update orders every x minutes
extern bool wantLongs = true; // do we want long positions
extern bool wantShorts = false; // 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 = 34; // the length of the EMA.. was previously fixed at 34
extern double GridMaxOpen = 0; // maximum number of open positions : implemented in v1.92
extern bool UseMACD = true; // 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 = 12; // parameters for MACD and OSMA
extern int emaSlow = 26; // parameters for MACD and OSMA
extern int signalPeriod = 9; // 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 double longGridCenter = 0; // defines the center point of a fixed width long grid
extern double shortGridCenter = 0; // defines the center point of a fixed width short grid
extern double longGridLow = 0; // defines the bottom of a fixed width long grid
extern double longGridHigh = 0; // defines the top of a fixed width long grid
extern double shortGridLow = 0; // defines the bottom of a fixed width short grid
extern double shortGridHigh = 0; // defines the top of a fixed width short grid
extern double profitTarget = 15000; // if > 0, will close out all positions once the $ target has been met
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.
// modified by cori. internal variables only
string GridName = "Grid"; // identifies the grid. allows for several co-existing grids - old variable.. shold not use any more
double LastUpdate = 0; // counter used to note time of last update
double startTime = 0; // counter to note trade start time.
double closedProfit = 0; // counts closed p&l
double openProfit = 0; // counts open p&l
double accumulatedProfit = 0; // for back testing only
bool haveHitTarget = false; // if there is a target, this flag says we have hit it
int openLongs = 0; // how many longs are open
int openShorts = 0; // how many shorts are open
bool gridActive = true; // is the grid active
bool gridOneShot = false; // is this a one shot? if so, it stops after the profitTarget has been reached
//+------------------------------------------------------------------+
//| 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 |
//+------------------------------------------------------------------------+
bool IsPosition(double atRate, double inRange, bool checkLongs )
{
int totalorders = OrdersTotal();
for(int i=0;i<totalorders;i++) // scan all orders and positions...
{
OrderSelect(i, SELECT_BY_POS);
// 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...
{ int type = OrderType();
if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // dont look for exact price but price proximity (less than gridsize) - added 0.9 because of floating point errors
{ if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) ) || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) )
{
return(true);
}
}
}
}
return(false);
}
//+------------------------------------------------------------------+
//| 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 opened long positions
if ( OrderType() == OP_BUY ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
//Close opened short positions
if ( OrderType() == OP_SELL ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 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 |
//+------------------------------------------------------------------------+
void CloseOrdersfromEMA( double theEMAValue )
{
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();
bool result = false;
//if (type > 1) Print(type," ",theEMAValue," ",OrderOpenPrice());
if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() );
if ( type == OP_BUYSTOP && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() );
if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() );
if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() );
}
}
return;
}
//+------------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
//| Close on profit target |
//+------------------------------------------------------------------+
void TestForProfit( int forMagic, double profittarget, bool testOpen, bool testHistory ) // based on trailing stop code from MT site... but modified as per Hiro
{
if (profittarget > 0 )
{
closedProfit = 0; // counts closed p&l
if (testHistory == true) {
int total = HistoryTotal();
for(int i=0;i<total;i++) // scan all closed / cancelled transactions
{
OrderSelect(i, SELECT_BY_POS, MODE_HISTORY );
if ( OrderSymbol() == Symbol() && OrderMagicNumber() == forMagic ) // only look if mygrid and symbol...
{
closedProfit = closedProfit + OrderProfit();
}
}
} else {
accumulatedProfit =0;
}
openProfit = 0; // counts open p&l
if (testOpen == true) {
total = OrdersTotal();
openLongs = 0;
openShorts = 0;
for(i=0;i<total;i++) // scan all open orders and positions
{
OrderSelect(i, SELECT_BY_POS );
if ( OrderSymbol() == Symbol() && OrderMagicNumber() == forMagic ) // only look if mygrid and symbol...
{
openProfit = openProfit + OrderProfit();
int type = OrderType();
if ( type == OP_BUY ) {openLongs=openLongs+1;}
if ( type == OP_SELL ) {openShorts=openShorts+1;}
}
}
}
if ( ( closedProfit + openProfit) >= (profittarget + accumulatedProfit) )
{
Print("Closing grid due to profit target");
ClosePendingOrdersAndPositions();
accumulatedProfit = accumulatedProfit + closedProfit + openProfit;
haveHitTarget = true;
if (gridOneShot==true) { gridActive = false; }
}
}
}
//+------------------------------------------------------------------+
//| 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()
void DoBE(int byPips)
{
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 - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) if (OrderStopLoss() != (OrderOpenPrice() + MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
if (OrderType() == OP_SELL) if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) if (OrderStopLoss() != (OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_POINT))) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
}
}
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
//----
int i, j,k, ticket, entermode, totalorders;
bool doit;
double point, startrate, traderate, temp;
//---- setup parameters
if ( TakeProfit <= 0 ) //
{ TakeProfit = GridSize; }
bool myWantLongs = wantLongs;
bool myWantShorts = wantShorts;
//---- test if we want to shutdown or suspend
if (suspendGrid == true) { // close unfilled orders and then test if profit target
CloseAllPendingOrders();
}
if (shutdownGrid == true) { // close all positions and orders. then exit.. there is nothing more to do
ClosePendingOrdersAndPositions();
return(0);
}
if (haveHitTarget == true) { // in case we hit target and there are still some open orders and positions
ClosePendingOrdersAndPositions();
if (gridOneShot==true) { gridActive = false; }
}
//----
if (gridActive == false) { // if grid not active, do nothing.
return(0);
}
//----
if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // we update the first time it is called and every UpdateInterval minutes
{
if (profitTarget >0)
{
TestForProfit(uniqueGridMagic, profitTarget, true, false );
if (!IsTesting()) {
Comment("Grid Type: ","Long Only"
);
}
}
LastUpdate = CurTime();
point = MarketInfo(Symbol(),MODE_POINT);
startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // round to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSize ;
startrate = k * point - GridSize*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(); }
}
if (limitEMA) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA);}
if (keepOpenTimeLimit > 0) DeleteAfter(keepOpenTimeLimit);
if (trailStop >0) TrailIt(trailStop);
if (BEPips >0) DoBE(BEPips);
if ( UseMACD || UseOsMA)
{
if ( UseMACD )
{
double Trigger0=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,0);
double Trigger1=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,1);
double Trigger2=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,2);
}
if ( UseOsMA )
{
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;
}
if (suspendGrid == true) { //profit target and exit conditions tested so finished
return(0);
}
Print("Trigs ", Trigger0," ",Trigger1," ",Trigger2," ",myWantLongs," ",myWantShorts," ",myGridSteps," ema ",myEMA," price ",Bid );
//Print("start 1 ",startrate);
for( i=0;i<myGridSteps;i++)
{
startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // round to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSize ;
startrate = k * point - GridSize*GridSteps/2*point ; // calculate the lowest entry point
traderate = startrate + i*point*GridSize + gridOffset*point;
if ( myWantLongs && (!limitEMA || traderate > myEMA))
{ if (longGridCenter > point) {
temp = GridSteps / 2;
k = temp;
startrate = longGridCenter - k * GridSize * point;
} else {
startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // round to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSize ;
startrate = k * point - GridSize*GridSteps/2*point ; // calculate the lowest entry point
}
traderate = startrate + i*point*GridSize + gridOffset*point;
// now test if traderate within limits
doit = true;
if (traderate < longGridLow) {doit = false;}
if ((traderate > longGridHigh) && (longGridHigh > point)) {doit = false;}
if (( IsPosition(traderate,point*GridSize,true) == false ) && (doit == true)) // test if i have no open orders close to my price: if so, put one on
{
double myStopLoss = 0;
if ( StopLoss > 0 )
{ myStopLoss = traderate-point*StopLoss ; }
if ( traderate > Ask )
{ entermode = OP_BUYSTOP; }
else
{ entermode = OP_BUYLIMIT ; }
if ( ((traderate > (Ask +minFromPrice*Point) ) && (wantBreakout)) || ((traderate <= (Ask-minFromPrice*Point) ) && (wantCounter)) )
{
// modified by cori. Using OrderMagicNumber to identify the trades of the grid
ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green);
}
}
}
if ( myWantShorts && (!limitEMA || traderate < myEMA))
{ if (shortGridCenter > point) {
temp = GridSteps / 2;
k = temp;
startrate = shortGridCenter - k * GridSize * point ;
} else {
startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // round to a number of ticks divisible by GridSize
k = startrate ;
k = k * GridSize ;
startrate = k * point - GridSize*GridSteps/2*point ; // calculate the lowest entry point
}
traderate = startrate + i*point*GridSize + gridOffset*point;
// now test if traderate within limits
doit = true;
if (traderate < shortGridLow) {doit = false;}
if ((traderate > shortGridHigh) && (shortGridHigh > point)) {doit = false;}
if ((IsPosition(traderate,point*GridSize,false)== false ) && (doit == true)) // test if i have no open orders close to my price: if so, put one on
{
myStopLoss = 0;
if ( StopLoss > 0 )
{ myStopLoss = traderate+point*StopLoss ; }
if ( traderate > Bid )
{ entermode = OP_SELLLIMIT; }
else
{ entermode = OP_SELLSTOP ; }
if ( ((traderate < (Bid -minFromPrice*Point) ) && (wantBreakout)) || ((traderate >= (Bid+minFromPrice*Point) ) && (wantCounter)) )
{
// modified by cori. Using OrderMagicNumber to identify the trades of the grid
ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red);
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Comments