Re: [MT_E and I] Re: Hidden Trailing Stop

//+--------------+
//|VirtualShell |
//+--------------+
#property copyright "Ron Thompson"
#property link "http://www.ForexMT4.com/"

// This EA is NEVER to be SOLD individually
// This EA is NEVER to be INCLUDED as part of a collection that is SOLD


// EA SPECIFIC


// user input
extern double Lots = 1.0 ;
extern double ProfitMade = 100 ;
extern double LossLimit = 200 ;
extern double BreakEven = 0 ;
extern double TrailStop = 15 ;

double myPoint; // support for 3/5 decimal places
bool TradeAllowed=false; // used to manage trades
int loopcount; // count of order attempts
int maxloop=5; // maximum number of attempts to handle errors
int LL2SL=10; // LossLimit to StopLoss server spread
int MagicNumber = 200903141510; // allows multiple experts to trade on same account
string TradeComment = "VS.txt"; // where to log information

// Bar handling
datetime bartime=0; // used to determine when a bar has moved
datetime vopsavetime=0; // used to determine when a bar has moved
datetime vopsynctime=0; // used to determine when a bar has moved


// Virtual Order Processor

#define vopct 100 // maximum numbers of orders to handle

int vopPTR; // pointer for ticket
int vopOrderTicket[vopct]; // ticket number
string vopOrderSymbol[vopct]; // which symbol
string vopOrderType[vopct]; // buy or sell order
double vopOrderLots[vopct]; // lot size
double vopOrderOpenPrice[vopct]; // Order Open Price
double vopOrderTakeProfit[vopct]; // take profit
double vopOrderStopLoss[vopct]; // stop loss
int vopOrderMagicNumber[vopct]; // MagicNumber


// used for verbose error logging
#include <stdlib.mqh>


//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled

int init()
{

//init the random generator
MathSrand(TimeLocal());

// get normalized Point based on Broker decimal places
myPoint = SetPoint();

CloseEverything();

//re-load the array, and sync it to real orders
vopLoad();
vopSync();


logwrite(TradeComment,"Init Complete");
Comment(" ");



}

//+----------------+
//| Custom DE-init |
//+----------------+
// Called ONCE when EA is removed from chart

int deinit()
{
// program is closing, save the array
vopSave();

logwrite(TradeComment,"DE-Init Complete");
Comment(" ");
}


//+-----------+
//| Main |
//+-----------+
// Called EACH TICK and each Bar[]

int start()
{

int cnt=0;
int gle=0;
int ticket=0;
int OrdersPerSymbol=0;

// stoploss and takeprofit and close control
double SL=0;
double TP=0;

double CurrentProfit=0;
double CurrentBasket=0;

// direction control
bool BUYme=false;
bool SELLme=false;

//safety counter
int loopcount=0;

//volume
double v1, v2, v3;
double v12p, v23p;


//Save the array once a minute in case of crash
if(vopsavetime!=iTime(Symbol(), 1, 0) )
{
vopsavetime=iTime(Symbol(), 1, 0) ;
vopSave();
}

//It is *possible* (but unlikely) for the array to
//get out of sync, so re-sync once every 15 minutes
if(vopsynctime!=iTime(Symbol(), 15, 0) )
{
vopsynctime=iTime(Symbol(), 15, 0) ;
vopSync();
}


OrdersPerSymbol=0;
for(cnt=OrdersTotal();cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++;
}
// one order at a time
if(OrdersPerSymbol==0) TradeAllowed=true;


// bar counting
if(bartime!=iTime(Symbol(), 0, 0) )
{
bartime=iTime(Symbol(), 0, 0) ;


//+-----------------------------+
//| Code here will execute once |
//| at the OPEN of a NEW BAR |
//+-----------------------------+


if(TradeAllowed && MathRand()> 16383) { OpenBuy(); }
if(TradeAllowed && MathRand()<=16383) { OpenSell(); }


//+------------+
//| End Insert |
//+------------+

}




//+-----------------------------+
//| Insert your indicator here |
//| And set either BUYme or |
//| SELLme true to place orders |
//+-----------------------------+


//+------------+
//| End Insert |
//+------------+



//
// Order Management
//

for(cnt=OrdersTotal();cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber )
{

vopPTR=vopSelect(OrderTicket());

if(vopOrderType[vopPTR]=="BUY")
{
CurrentProfit=(Bid-vopOrderOpenPrice[vopPTR]) ;

// Modify for break even
//=======================
if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
{
vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]+(Ask-Bid);
logwrite(TradeComment,"BREAKEVEN BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Bid="+Bid+" Ask="+Ask);
}

// check for trailing stop
//=========================
if( TrailStop>0)
{
// This starts trailing after 'TrailStop' pips of profit
if(Close[0]>=vopOrderOpenPrice[vopPTR]+(TrailStop*myPoint) )
{
// if you're here, then you're at least TrailStop pips in profit
if( Bid-(TrailStop*myPoint) > vopOrderStopLoss[vopPTR] )
{
vopOrderStopLoss[vopPTR]=Bid-(TrailStop*myPoint);
logwrite(TradeComment,"TRAILSTOP BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Bid="+Bid);
}
}
}

if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint)) CloseBuy("PROFIT");
if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint)) CloseBuy("LOSS");
if(vopOrderStopLoss[vopPTR]>0 && Close[0]<=vopOrderStopLoss[vopPTR] ) CloseBuy("STOPLOSS");

} //BUY




if(vopOrderType[vopPTR]=="SELL")
{
CurrentProfit=(vopOrderOpenPrice[vopPTR]-Ask);

// Modify for break even
//=======================
if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
{
vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]-(Ask-Bid);
logwrite(TradeComment,"BREAKEVEN SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Ask="+Ask+" Bid="+Bid);
}

// check for trailing stop
//=========================
if( TrailStop>0)
{
// This starts trailing after 'TrailStop' pips of profit
if(Close[0]<=vopOrderOpenPrice[vopPTR]-(TrailStop*myPoint) )
{
// if you're here, then you're at least TrailStop pips in profit
if( Ask+(TrailStop*myPoint) < vopOrderStopLoss[vopPTR] )
{
vopOrderStopLoss[vopPTR]=Ask+(TrailStop*myPoint);
logwrite(TradeComment,"TRAILSTOP SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Ask="+Ask);
}
}
}

if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint) ) CloseSell("PROFIT");
if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint) ) CloseSell("LOSS");
if(vopOrderStopLoss[vopPTR]>0 && Close[0]>=vopOrderStopLoss[vopPTR] ) CloseSell("STOPLOSS");


} //sell

} //OrderSymbol

} // for

} // start()


//+-----------------+
//| CloseEverything |
//+-----------------+
// Closes all OPEN and PENDING orders

int CloseEverything()
{
int i;

for(i=OrdersTotal();i>=0;i--)
{

OrderSelect(i, SELECT_BY_POS);
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
vopPTR=vopSelect(OrderTicket());

if(OrderType()==OP_BUY) CloseBuy ("CLOSEEVERYTHING");
if(OrderType()==OP_SELL) CloseSell("CLOSEEVERYTHING");
if(OrderType()==OP_BUYLIMIT) OrderDelete( vopOrderTicket[vopPTR] );
if(OrderType()==OP_SELLLIMIT) OrderDelete( vopOrderTicket[vopPTR] );
if(OrderType()==OP_BUYSTOP) OrderDelete( vopOrderTicket[vopPTR] );
if(OrderType()==OP_SELLSTOP) OrderDelete( vopOrderTicket[vopPTR] );
}

Sleep(1000);

} //for

} // closeeverything



// log data to a file name passed in
// print everything regardless of log setting
void logwrite (string filename, string mydata)
{
int myhandle;
string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);

Print(mydata+" "+gregorian);

// don't log anything if testing
if(IsTesting()) return(0);

myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
if(myhandle>0)
{
FileSeek(myhandle,0,SEEK_END);
FileWrite(myhandle, mydata+" "+gregorian);
FileClose(myhandle);
}
}



//ENTRY LONG (buy, Ask)
void OpenBuy()
{
int gle=0;
int ticket=0;

int loopcount=0;

while(true)
{
// place order - NO TP OR SL
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,TradeComment,MagicNumber,White);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+Ask+" Bid="+Bid+" Lots="+Lots);
vopOrderOpen(ticket, "BUY", Symbol(), Lots, Ask, ProfitMade, LossLimit, MagicNumber);
//TradeAllowed=false;
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- Placing BUY order: Lots="+Lots+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
Sleep(500);
RefreshRates();

// give up after loopcount tries
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on placing BUY order");
return(gle);
}

}

}//while - place order

}//BUYme



//ENTRY SHORT (sell, Bid)
void OpenSell()
{
int gle=0;
int ticket=0;

double SL=0;
double TP=0;
int loopcount=0;

while(true)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,0,0,0,TradeComment,MagicNumber,Red);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+Bid+" Ask="+Ask+" Lots="+Lots);
vopOrderOpen(ticket, "SELL", Symbol(), Lots, Bid, ProfitMade, LossLimit, MagicNumber);
//TradeAllowed=false;
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- placing SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
Sleep(500);
RefreshRates();

loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order");
return(gle);
}

}

}//while - place order

}//SELLme



void CloseBuy (string myInfo)
{
int gle;
int cnt;

int loopcount=0;

string bBD=" Bid="+Bid;
string bAS=" Ask="+Ask;
string bTK=" Ticket="+vopOrderTicket[vopPTR];
string bSL=" SL="+vopOrderStopLoss[vopPTR];
string bTP=" TP="+vopOrderTakeProfit[vopPTR];
string bPM;
string bLL;
string bER;

bPM=" PM="+ProfitMade;
bLL=" LL="+LossLimit;

while(true)
{
OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Bid,0,White);
gle=GetLastError();
if(gle==0)
{
vopOrderClose(vopOrderTicket[vopPTR], myInfo);
logwrite(TradeComment,"CLOSE BUY "+myInfo+ bBD+ bAS+ bTK+ bSL+ bTP+ bPM+ bLL);
break;
}
else
{
bER=" error="+gle+" "+ErrorDescription(gle);
logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
Sleep(500);
RefreshRates();
}


loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
return(gle);
}

}//while

}


void CloseSell (string myInfo)
{
int gle;
int cnt;

int loopcount=0;

string sBD=" Bid="+Bid;
string sAS=" Ask="+Ask;
string sTK=" Ticket="+vopOrderTicket[vopPTR];
string sSL=" SL="+vopOrderStopLoss[vopPTR];
string sTP=" TP="+vopOrderTakeProfit[vopPTR];
string sPM;
string sLL;
string sER;

sPM=" PM="+ProfitMade;
sLL=" LL="+LossLimit;

while(true)
{
OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Ask,0,Red);
gle=GetLastError();
sER=" error="+gle+" "+ErrorDescription(gle);

if(gle==0)
{
vopOrderClose(vopOrderTicket[vopPTR], myInfo);
logwrite(TradeComment,"CLOSE SELL "+myInfo+ sAS+ sBD+ sTK+ sSL+ sTP+ sPM+ sLL);
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
RefreshRates();
Sleep(500);
}

loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
return(gle);
}

}//while
}


// Function to correct the value of Point
// for brokers that add an extra digit to price
// Courtesy of Robert Hill

double SetPoint()
{
double mPoint;

if (Digits < 4)
mPoint = 0.01;
else
mPoint = 0.0001;

return(mPoint);
}


// Virtual Order Processor - open order
void vopOrderOpen (int vTKT, string vTYP, string vSYM, double vLOTS, double vOOP, double vTP, double vSL, int vMAG)
{
int i;
logwrite(TradeComment,Symbol()+" vopOPEN: "+vTYP+" symbol="+vSYM+" ticket "+vTKT+" OpenPrice="+vOOP+" Lots="+vLOTS+" StopLoss="+vSL+" TakeProfit="+vTP+" MagicNumber"+vMAG );

// find next available ticket slot
for(i=0; i<=99; i++)
{
if(vopOrderTicket[i]==0) break;
}
vopOrderTicket[i]=vTKT;
vopOrderType[i]=vTYP;
vopOrderSymbol[i]=vSYM;
vopOrderLots[i]=vLOTS;
vopOrderOpenPrice[i]=vOOP;
vopOrderTakeProfit[i]=vTP;
vopOrderStopLoss[i]=vSL;
vopOrderMagicNumber[i]=vMAG;
}


// Virtual Order Processor - close order
void vopOrderClose (int vTKT, string vINFO)
{
int i;

// find next available ticket slot
for(i=0; i<=99; i++)
{
if(vopOrderTicket[i]==vTKT) break;
}
logwrite(TradeComment,Symbol()+" vopCLOSE "+vINFO+": "+vopOrderType[i]+" symbol="+vopOrderSymbol[i]+" ticket "+vopOrderTicket[i]+" OpenPrice="+vopOrderOpenPrice[i]+" Lots="+vopOrderLots[i]+" StopLoss="+vopOrderStopLoss[i]+" TakeProfit="+vopOrderTakeProfit[i] );

vopOrderTicket[i]=0;
vopOrderType[i]=" ";
vopOrderSymbol[i]=" ";
vopOrderLots[i]=0;
vopOrderOpenPrice[i]=0;
vopOrderTakeProfit[i]=0;
vopOrderStopLoss[i]=0;
vopOrderMagicNumber[i]=0;
}


// Virtual Order Processor - find order by ticket
int vopSelect (int vTKT)
{
int i;

// find next available ticket slot
for(i=0; i<=99; i++)
{
if(vopOrderTicket[i]==vTKT) break;
}
return(i);
}




// VOP save routine once a minute
void vopSave ()
{

//SAVE routine goes here

}



// VOP load routine
void vopLoad ()
{

//LOAD routine goes here

}



// VOP sync routine used after restore
void vopSync ()
{

//SYNC routine goes here

}

It appears to be working ok. Here's another slightly modified version with a buy/sell and TrailStop and TP that should allow several orders to activate the trailing stop. See the list below to show it working on a SELL order. (The journal is in reverse order)

Back test this in Visual mode, and look in the Journal tab as it runs, and you should see the log statements show up as the stop moves.

You *DO* have to differentiate between buy/bid and sell/ask when trailing as well.

Hope this hasn't confused the issue.

Ron


EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29080000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29090000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29100000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29110000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29120000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29130000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29140000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29150000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29170000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29180000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29190000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29200000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29210000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29220000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29230000
EURUSDm,H4: TRAILSTOP SELL Ticket=395 SL=1.29270000


bluey39to wrote:

Ron,
I tried your code, the Trailing part, and unfortunately it had the same problem. The Stop moves up and down with the changing price.
I can't work out why.

Hopefully someone else has a solution.

--- In MetaTrader_Experts_and_Indicators@yahoogroups.com, Ron Thompson <ron@...> wrote:
>
>
> Here's a copy of code I'm currently working on that hides almost all of
> the order process.
>
> It has a structure for order management, and procedures you can call to
> replace the standard order functions.
>
> It is _*NOT*_ complete, as I still have to write the load, save and sync
> functions. I really hate not having structures, which would make the
> process so simple.
>
> Ron(ForexMT4)
>
>
> bluey39to wrote:
> >
> > Thanks for reply Robert.
> > I'm talking about a hidden trailing stop that doesn't use the
> > "ModifyOrder" function. I'm not worried about a disconnect, as I can
> > easily place a firm stop when I open the trade.
> > This is a hidden stop, that if price moves below (on a buy), it will
> > trigger a sell. Obviously that part is easy to be hidden, but to have
> > it trail up, I can't seem to solve.
> >
> > Here's a snippit of code:
> >
> > //---set up---------------------
> > int HiddenTrailingStopPips = 5;
> > double HiddenTrailingStopPrice = 0;
> >
> > //--after finding any open Buy orders
> >
> > if ((Bid-OrderOpenPrice() > 0) && // If price has moved up from when
> > order was opened, and
> > (HiddenTrailingStopPrice < Bid - Point*HiddenTrailingStopPips)) // If
> > our Hidden Stop Value is lower than it should be?
> > {
> > HiddenTrailingStopPrice = Bid - Point*HiddenTrailingStopPips; // Set
> > new value for Hidden Stop Value
> > }
> >
> > // closing if stop hit--------------------
> >
> > if (Bid <= HiddenTrailingStopPrice) // Price has moved below our
> > HiddenStopLine
> > {
> > OrderClose(OrderTicket(),OrderLots(),Bid,9,Violet); // Close BUY order
> > }
> >
> >
> > The above doesn't work. The HiddenTrailingStopPrice, moves up and
> > down, and not just up as it should. Any ideas appreciated.
> >
> > --- In MetaTrader_Experts_and_Indicators@yahoogroups.com
> > <mailto:MetaTrader_Experts_and_Indicators%40yahoogroups.com>, Robert
> > Hill <robydoby314@> wrote:
> > >
> > > bluey39to,
> > > What type of trailing stop are you using?
> > >
> > > It would be easy to modify the existing TraingStop EA to use hidden
> > trailing but if there is a disconnect then the broker might not have
> > any stoploss set.
> > >
> > > An alternative is to have the broker sent the hidden value plus or
> > minus a set number of pips for protection.
> > >
> > > For example if the stop should be 1.4780 on a buy the broker might
> > get 1.4760.
> > > The EA would close the trade at 1.4780 if no further movement
> > positive movement.
> > >
> > > Otherwise you could send me your code privately and I will see what
> > I can do.
> > >
> > >
> > > Robert
> > >
> > > --- On Sat, 3/14/09, bluey39to <dbyrt@> wrote:
> > >
> > > From: bluey39to <dbyrt@>
> > > Subject: [MT_E and I] Hidden Trailing Stop
> > > To: MetaTrader_Experts_and_Indicators@yahoogroups.com
> > <mailto:MetaTrader_Experts_and_Indicators%40yahoogroups.com>
> > > Date: Saturday, March 14, 2009, 12:45 PM
> > >
> > >
> > >
> > >
> > >
> > > After many searches and trying to build this myself, I've not
> > managed to find a hidden trailing stop. Plenty of hidden TP and hidden
> > Stops, but the hidden trailing seems a bit elusive. Has anyone created
> > a bit of code to do this?
> > > My attempts; the hidden stop value moves up with each new high, but
> > when the price moves back down, so does my stop. All kinds of 'if'
> > statements tried, but can't get it to work.
> > >
> > > Any thoughts?
> > >
> > > Regards
> > > bluey39to
> > >
> >
> >
>
> //+--------------+
> //|VirtualShell |
> //+--------------+
> #property copyright "Ron Thompson"
> #property link "http://www.ForexMT4.com/"
>
> // This EA is NEVER to be SOLD individually
> // This EA is NEVER to be INCLUDED as part of a collection that is SOLD
>
>
> // EA SPECIFIC
>
>
> // user input
> extern double Lots = 0.5 ;
> extern double ProfitMade = 0 ;
> extern double LossLimit = 0 ;
> extern double BreakEven = 7 ;
> extern double TrailStop = 15 ;
>
> double myPoint; // support for 3/5 decimal places
> bool TradeAllowed=false; // used to manage trades
> int loopcount; // count of order attempts
> int maxloop=5; // maximum number of attempts to handle errors
> int LL2SL=10; // LossLimit to StopLoss server spread
> int MagicNumber = 200903141510; // allows multiple experts to trade on same account
> string TradeComment = "VS.txt"; // where to log information
>
> // Bar handling
> datetime bartime=0; // used to determine when a bar has moved
> datetime vopsavetime=0; // used to determine when a bar has moved
> datetime vopsynctime=0; // used to determine when a bar has moved
>
>
> // Virtual Order Processor
>
> #define vopct 100 // maximum numbers of orders to handle
>
> int vopPTR; // pointer for ticket
> int vopOrderTicket[vopct]; // ticket number
> string vopOrderSymbol[vopct]; // which symbol
> string vopOrderType[vopct]; // buy or sell order
> double vopOrderLots[vopct]; // lot size
> double vopOrderOpenPrice[vopct]; // Order Open Price
> double vopOrderTakeProfit[vopct]; // take profit
> double vopOrderStopLoss[vopct]; // stop loss
> int vopOrderMagicNumber[vopct]; // MagicNumber
>
>
> // used for verbose error logging
> #include <stdlib.mqh>
>
>
> //+-------------+
> //| Custom init |
> //|-------------+
> // Called ONCE when EA is added to chart or recompiled
>
> int init()
> {
> // get normalized Point based on Broker decimal places
> myPoint = SetPoint();
>
> //re-load the array, and sync it to real orders
> vopLoad();
> vopSync();
>
> logwrite(TradeComment,"Init Complete");
> Comment(" ");
>
>
>
> }
>
> //+----------------+
> //| Custom DE-init |
> //+----------------+
> // Called ONCE when EA is removed from chart
>
> int deinit()
> {
> // program is closing, save the array
> vopSave();
>
> logwrite(TradeComment,"DE-Init Complete");
> Comment(" ");
> }
>
>
> //+-----------+
> //| Main |
> //+-----------+
> // Called EACH TICK and each Bar[]
>
> int start()
> {
>
> int cnt=0;
> int gle=0;
> int ticket=0;
> int OrdersPerSymbol=0;
>
> // stoploss and takeprofit and close control
> double SL=0;
> double TP=0;
>
> double CurrentProfit=0;
> double CurrentBasket=0;
>
> // direction control
> bool BUYme=false;
> bool SELLme=false;
>
> //safety counter
> int loopcount=0;
>
> //volume
> double v1, v2, v3;
> double v12p, v23p;
>
>
> //Save the array once a minute in case of crash
> if(vopsavetime!=iTime(Symbol(), 1, 0) )
> {
> vopsavetime=iTime(Symbol(), 1, 0) ;
> vopSave();
> }
>
> //It is *possible* (but unlikely) for the array to
> //get out of sync, so re-sync once every 15 minutes
> if(vopsynctime!=iTime(Symbol(), 15, 0) )
> {
> vopsynctime=iTime(Symbol(), 15, 0) ;
> vopSync();
> }
>
>
> // bar counting
> if(bartime!=iTime(Symbol(), 0, 0) )
> {
> bartime=iTime(Symbol(), 0, 0) ;
>
>
> //+-----------------------------+
> //| Code here will execute once |
> //| at the OPEN of a NEW BAR |
> //+-----------------------------+
>
> v1=iVolume(Symbol(),0,1);
> v2=iVolume(Symbol(),0,2);
> v3=iVolume(Symbol(),0,3);
>
> logwrite(TradeComment,"New Bar v1="+v1+" v2="+v2+" v3="+v3);
>
> if(TradeAllowed) CloseEverything();
> if(TradeAllowed && v1>v2 && v2>v3) { OpenBuy(); OpenSell(); }
>
> // prevents 1st order when EA put on chart
> TradeAllowed=true;
>
> //+------------+
> //| End Insert |
> //+------------+
>
> }
>
>
>
>
> //+-----------------------------+
> //| Insert your indicator here |
> //| And set either BUYme or |
> //| SELLme true to place orders |
> //+-----------------------------+
>
>
> //+------------+
> //| End Insert |
> //+------------+
>
>
>
> //
> // Order Management
> //
>
> for(cnt=OrdersTotal();cnt>=0;cnt--)
> {
> OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
> if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber )
> {
>
> vopPTR=vopSelect(OrderTicket());
>
> if(vopOrderType[vopPTR]=="BUY")
> {
> CurrentProfit=(Bid-vopOrderOpenPrice[vopPTR]) ;
>
> // Modify for break even
> //=======================
> if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
> {
> vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]+(Ask-Bid);
> logwrite(TradeComment,"BREAKEVEN BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Bid="+Bid+" Ask="+Ask);
> }
>
> // check for trailing stop
> //=========================
> if( TrailStop>0)
> {
> // This starts trailing after 'TrailStop' pips of profit
> if(Close[0]>=vopOrderOpenPrice[vopPTR]+(TrailStop*myPoint) )
> {
> // if you're here, then you're at least TrailStop pips in profit
> if( Bid-(TrailStop*myPoint) > vopOrderStopLoss[vopPTR] )
> {
> vopOrderStopLoss[vopPTR]=Bid-(TrailStop*myPoint);
> logwrite(TradeComment,"TRAILSTOP BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Bid="+Bid);
> }
> }
> }
>
> if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint)) CloseBuy("PROFIT");
> if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint)) CloseBuy("LOSS");
> if(vopOrderStopLoss[vopPTR]>0 && Close[0]<=vopOrderStopLoss[vopPTR] ) CloseBuy("STOPLOSS");
>
> } //BUY
>
>
>
>
> if(vopOrderType[vopPTR]=="SELL")
> {
> CurrentProfit=(vopOrderOpenPrice[vopPTR]-Ask);
>
> // Modify for break even
> //=======================
> if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
> {
> vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]-(Ask-Bid);
> logwrite(TradeComment,"BREAKEVEN SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Ask="+Ask+" Bid="+Bid);
> }
>
> // check for trailing stop
> //=========================
> if( TrailStop>0)
> {
> // This starts trailing after 'TrailStop' pips of profit
> if(Close[0]<=vopOrderOpenPrice[vopPTR]-(TrailStop*myPoint) )
> {
> if( Ask+(TrailStop*myPoint) < vopOrderStopLoss[vopPTR] )
> {
> vopOrderStopLoss[vopPTR]=Ask+(TrailStop*myPoint);
> logwrite(TradeComment,"TRAILSTOP SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Ask="+Ask);
> }
> }
> }
>
> if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint) ) CloseSell("PROFIT");
> if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint) ) CloseSell("LOSS");
> if(vopOrderStopLoss[vopPTR]>0 && Close[0]>=vopOrderStopLoss[vopPTR] ) CloseSell("STOPLOSS");
>
>
> } //sell
>
> } //OrderSymbol
>
> } // for
>
> } // start()
>
>
> //+-----------------+
> //| CloseEverything |
> //+-----------------+
> // Closes all OPEN and PENDING orders
>
> int CloseEverything()
> {
> int i;
>
> for(i=OrdersTotal();i>=0;i--)
> {
>
> OrderSelect(i, SELECT_BY_POS);
> if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
> {
> vopPTR=vopSelect(OrderTicket());
>
> if(OrderType()==OP_BUY) CloseBuy ("CLOSEEVERYTHING");
> if(OrderType()==OP_SELL) CloseSell("CLOSEEVERYTHING");
> if(OrderType()==OP_BUYLIMIT) OrderDelete( vopOrderTicket[vopPTR] );
> if(OrderType()==OP_SELLLIMIT) OrderDelete( vopOrderTicket[vopPTR] );
> if(OrderType()==OP_BUYSTOP) OrderDelete( vopOrderTicket[vopPTR] );
> if(OrderType()==OP_SELLSTOP) OrderDelete( vopOrderTicket[vopPTR] );
> }
>
> Sleep(1000);
>
> } //for
>
> } // closeeverything
>
>
>
> // log data to a file name passed in
> // print everything regardless of log setting
> void logwrite (string filename, string mydata)
> {
> int myhandle;
> string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);
>
> Print(mydata+" "+gregorian);
>
> // don't log anything if testing
> if(IsTesting()) return(0);
>
> myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
> if(myhandle>0)
> {
> FileSeek(myhandle,0,SEEK_END);
> FileWrite(myhandle, mydata+" "+gregorian);
> FileClose(myhandle);
> }
> }
>
>
>
> //ENTRY LONG (buy, Ask)
> void OpenBuy()
> {
> int gle=0;
> int ticket=0;
>
> int loopcount=0;
>
> while(true)
> {
> // place order - NO TP OR SL
> ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,TradeComment,MagicNumber,White);
> gle=GetLastError();
> if(gle==0)
> {
> logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+Ask+" Bid="+Bid+" Lots="+Lots);
> vopOrderOpen(ticket, "BUY", Symbol(), Lots, Ask, ProfitMade, LossLimit, MagicNumber);
> //TradeAllowed=false;
> break;
> }
> else
> {
> logwrite(TradeComment,"-----ERROR----- Placing BUY order: Lots="+Lots+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
> Sleep(500);
> RefreshRates();
>
> // give up after loopcount tries
> loopcount++;
> if(loopcount>maxloop)
> {
> logwrite(TradeComment,"-----ERROR----- Giving up on placing BUY order");
> return(gle);
> }
>
> }
>
> }//while - place order
>
> }//BUYme
>
>
>
> //ENTRY SHORT (sell, Bid)
> void OpenSell()
> {
> int gle=0;
> int ticket=0;
>
> double SL=0;
> double TP=0;
> int loopcount=0;
>
> while(true)
> {
> ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,0,0,0,TradeComment,MagicNumber,Red);
> gle=GetLastError();
> if(gle==0)
> {
> logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+Bid+" Ask="+Ask+" Lots="+Lots);
> vopOrderOpen(ticket, "SELL", Symbol(), Lots, Bid, ProfitMade, LossLimit, MagicNumber);
> //TradeAllowed=false;
> break;
> }
> else
> {
> logwrite(TradeComment,"-----ERROR----- placing SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
> Sleep(500);
> RefreshRates();
>
> loopcount++;
> if(loopcount>maxloop)
> {
> logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order");
> return(gle);
> }
>
> }
>
> }//while - place order
>
> }//SELLme
>
>
>
> void CloseBuy (string myInfo)
> {
> int gle;
> int cnt;
>
> int loopcount=0;
>
> string bBD=" Bid="+Bid;
> string bAS=" Ask="+Ask;
> string bTK=" Ticket="+vopOrderTicket[vopPTR];
> string bSL=" SL="+vopOrderStopLoss[vopPTR];
> string bTP=" TP="+vopOrderTakeProfit[vopPTR];
> string bPM;
> string bLL;
> string bER;
>
> bPM=" PM="+ProfitMade;
> bLL=" LL="+LossLimit;
>
> while(true)
> {
> OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Bid,0,White);
> gle=GetLastError();
> if(gle==0)
> {
> vopOrderClose(vopOrderTicket[vopPTR], myInfo);
> logwrite(TradeComment,"CLOSE BUY "+myInfo+ bBD+ bAS+ bTK+ bSL+ bTP+ bPM+ bLL);
> break;
> }
> else
> {
> bER=" error="+gle+" "+ErrorDescription(gle);
> logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
> Sleep(500);
> RefreshRates();
> }
>
>
> loopcount++;
> if(loopcount>maxloop)
> {
> logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
> return(gle);
> }
>
> }//while
>
> }
>
>
> void CloseSell (string myInfo)
> {
> int gle;
> int cnt;
>
> int loopcount=0;
>
> string sBD=" Bid="+Bid;
> string sAS=" Ask="+Ask;
> string sTK=" Ticket="+vopOrderTicket[vopPTR];
> string sSL=" SL="+vopOrderStopLoss[vopPTR];
> string sTP=" TP="+vopOrderTakeProfit[vopPTR];
> string sPM;
> string sLL;
> string sER;
>
> sPM=" PM="+ProfitMade;
> sLL=" LL="+LossLimit;
>
> while(true)
> {
> OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Ask,0,Red);
> gle=GetLastError();
> sER=" error="+gle+" "+ErrorDescription(gle);
>
> if(gle==0)
> {
> vopOrderClose(vopOrderTicket[vopPTR], myInfo);
> logwrite(TradeComment,"CLOSE SELL "+myInfo+ sAS+ sBD+ sTK+ sSL+ sTP+ sPM+ sLL);
> break;
> }
> else
> {
> logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
> RefreshRates();
> Sleep(500);
> }
>
> loopcount++;
> if(loopcount>maxloop)
> {
> logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
> return(gle);
> }
>
> }//while
> }
>
>
> // Function to correct the value of Point
> // for brokers that add an extra digit to price
> // Courtesy of Robert Hill
>
> double SetPoint()
> {
> double mPoint;
>
> if (Digits < 4)
> mPoint = 0.01;
> else
> mPoint = 0.0001;
>
> return(mPoint);
> }
>
>
> // Virtual Order Processor - open order
> void vopOrderOpen (int vTKT, string vTYP, string vSYM, double vLOTS, double vOOP, double vTP, double vSL, int vMAG)
> {
> int i;
> logwrite(TradeComment,Symbol()+" vopOPEN: "+vTYP+" symbol="+vSYM+" ticket "+vTKT+" OpenPrice="+vOOP+" Lots="+vLOTS+" StopLoss="+vSL+" TakeProfit="+vTP+" MagicNumber"+vMAG );
>
> // find next available ticket slot
> for(i=0; i<=99; i++)
> {
> if(vopOrderTicket[i]==0) break;
> }
> vopOrderTicket[i]=vTKT;
> vopOrderType[i]=vTYP;
> vopOrderSymbol[i]=vSYM;
> vopOrderLots[i]=vLOTS;
> vopOrderOpenPrice[i]=vOOP;
> vopOrderTakeProfit[i]=vTP;
> vopOrderStopLoss[i]=vSL;
> vopOrderMagicNumber[i]=vMAG;
> }
>
>
> // Virtual Order Processor - close order
> void vopOrderClose (int vTKT, string vINFO)
> {
> int i;
>
> // find next available ticket slot
> for(i=0; i<=99; i++)
> {
> if(vopOrderTicket[i]==vTKT) break;
> }
> logwrite(TradeComment,Symbol()+" vopCLOSE "+vINFO+": "+vopOrderType[i]+" symbol="+vopOrderSymbol[i]+" ticket "+vopOrderTicket[i]+" OpenPrice="+vopOrderOpenPrice[i]+" Lots="+vopOrderLots[i]+" StopLoss="+vopOrderStopLoss[i]+" TakeProfit="+vopOrderTakeProfit[i] );
>
> vopOrderTicket[i]=0;
> vopOrderType[i]=" ";
> vopOrderSymbol[i]=" ";
> vopOrderLots[i]=0;
> vopOrderOpenPrice[i]=0;
> vopOrderTakeProfit[i]=0;
> vopOrderStopLoss[i]=0;
> vopOrderMagicNumber[i]=0;
> }
>
>
> // Virtual Order Processor - find order by ticket
> int vopSelect (int vTKT)
> {
> int i;
>
> // find next available ticket slot
> for(i=0; i<=99; i++)
> {
> if(vopOrderTicket[i]==vTKT) break;
> }
> return(i);
> }
>
>
>
>
> // VOP save routine once a minute
> void vopSave ()
> {
>
> //SAVE routine goes here
>
> }
>
>
>
> // VOP load routine
> void vopLoad ()
> {
>
> //LOAD routine goes here
>
> }
>
>
>
> // VOP sync routine used after restore
> void vopSync ()
> {
>
> //SYNC routine goes here
>
> }
>



__._,_.___


For archives of Experts and Indicators from the MetaTrader Experts and Indicators Group
See http://www.forexmt4.com/ or http://www.lightpatch.com/forex




Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___