Re: [MT_E and I] Hidden Trailing Stop


Yes, the trailing stop code does work.

The use of an array (and all the pieces of it) allow you to manage several different orders.

If the account is ever only going to have one order open at a time, then single variables will work ok.

Max will always be == Bid  because you did:

double Max = Bid;

which sets it the same.  You'll need to declare MAX as a global so you're not declaring it every tick, and reset it to Bid when the order closes.

... does that make sense?

Ron(ForexMT4)


bluey39to wrote:

Thanks Ron,
Does your hidden trailing stop part work?
It's not far from my code, just that you're using an array.

At its simplest, the code is trying to do this:

double Max = Bid;

if (Bid > Max) // if Bid goes up
{
Max = Bid; // we want to store it as Max, and use it later
}

However, Max appears to always be the same as Bid, even if Bid goes below the Max, Max copies it. Do you know if an array the only way around this?

--- 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

__,_._,___