CandleStickTrailingStop Weirdness

Post Reply
Radar
Trader
Posts: 437
Joined: Fri Mar 23, 2012 5:39 pm
Location: Round the bend ;)

CandleStickTrailingStop Weirdness

Post by Radar »

Hey Gang,

I'm trying to get a candlestick trailing stoploss working, but have come across a very strange situation...

The trailing stop works fine for Buys, but for Sells, I have to insert either an alert, or Sleep(1);...

Here's the code, (adapted from Steve's shell)...

Code: Select all

void CandlestickTrailingStop()
{
   
   //Trails the stop at the hi/lo of the previous candle shifted by the user choice.
   //Only tries to do this once per bar, so an invalid stop error will only be generated once. I could code for
   //a too-close sl, but cannot be arsed. Coders, sort this out for yourselves.
   
   if (OldCstBars == iBars(NULL, CstTimeFrame)) return;
   OldCstBars = iBars(NULL, CstTimeFrame);

   //if (OrderProfit() < 0) return;//Nothing to do
   double NewStop;
   bool modify=false;
   bool result;
   
   for (int i=OrdersTotal()-1 ; i>=0 ; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      if (OrderMagicNumber() == MagicNumber)
      if (OrderSymbol() == Symbol())
      {
         int sl = OrderStopLoss();
         int ticket = OrderTicket();
         if (OrderType() == OP_BUY)
         {
            if ((BreakEven) && (sl < OrderOpenPrice())) continue;
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) > OrderOpenPrice())
            if ((!BreakEven) && (sl < OrderOpenPrice())) sl = OrderOpenPrice();
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) > sl)
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) < (Bid - ((MarketInfo(Symbol(), MODE_STOPLEVEL)/factor)/10)))
            {
               NewStop = NormalizeDouble(iLow(NULL, CstTimeFrame, CstTrailCandles), Digits);
               //Check that the new stop is > the old. Exit the function if not.
               if (NewStop < OrderStopLoss() || CloseEnough(NewStop, OrderStopLoss()) ) continue;
                modify = true;   
            }
            //if (iLow(NULL, CstTimeFrame, CstTrailCandles) > sl)
         }//if (OrderType == OP_BUY)
   
         if (OrderType() == OP_SELL)
         {
            if ((BreakEven) && (sl > OrderOpenPrice())) continue;
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < OrderOpenPrice())
            if ((!BreakEven) && (sl > OrderOpenPrice())) sl = OrderOpenPrice();
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) > (Ask + ((MarketInfo(Symbol(), MODE_STOPLEVEL)/factor)/10)))
Alert("If I remove this alert, candlesticktrailingstop only works for Buys"); // Why? Why?? WHY???
            {
               NewStop = NormalizeDouble(iHigh(NULL, CstTimeFrame, CstTrailCandles), Digits);
               //Check that the new stop is < the old. Exit the function if not.
               if (NewStop > OrderStopLoss() || CloseEnough(NewStop, OrderStopLoss()) ) continue;
               if (NewStop > OrderOpenPrice() ) continue;
               modify = true;   
            }//if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
         }//if (OrderType() == OP_SELL)
   
         //Move 'hard' stop loss whether hidden or not. Don't want to risk losing a breakeven through disconnect.
         if (modify)
         {
            while (IsTradeContextBusy() ) Sleep(100);
            result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
            if (!result) ReportError(" CandlestickTrailingStop()", slm);
            if (!result) 
            {
               ReportError(" CandlestickTrailingStop()", slm);
               OldCstBars = 0;
            }//if (!result)
          }//if (modify)
      }
   }
   return;
}//End void CandlestickTrailingStop()
I just don't get it... My old eyes, and newbie code skills don't see anything different between the Buy code and the Sell code, (other than swapping the <> around), but the sod just won't work without the Sleep(1); or an alert.

Your help will be greatly appreciated.

Have fun!

Radar =8^)
Check out my new, (well, old now), manual trade & automatic scale-in manager,
StackManV2
MrLong

Re: CandleStickTrailingStop Weirdness

Post by MrLong »

Radar wrote:Hey Gang,

I'm trying to get a candlestick trailing stoploss working, but have come across a very strange situation...

The trailing stop works fine for Buys, but for Sells, I have to insert either an alert, or Sleep(1);...

Here's the code, (adapted from Steve's shell)...

Code: Select all

void CandlestickTrailingStop()
{
   
   //Trails the stop at the hi/lo of the previous candle shifted by the user choice.
   //Only tries to do this once per bar, so an invalid stop error will only be generated once. I could code for
   //a too-close sl, but cannot be arsed. Coders, sort this out for yourselves.
   
   if (OldCstBars == iBars(NULL, CstTimeFrame)) return;
   OldCstBars = iBars(NULL, CstTimeFrame);

   //if (OrderProfit() < 0) return;//Nothing to do
   double NewStop;
   bool modify=false;
   bool result;
   
   for (int i=OrdersTotal()-1 ; i>=0 ; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      if (OrderMagicNumber() == MagicNumber)
      if (OrderSymbol() == Symbol())
      {
         int sl = OrderStopLoss();
         int ticket = OrderTicket();
         if (OrderType() == OP_BUY)
         {
            if ((BreakEven) && (sl < OrderOpenPrice())) continue;
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) > OrderOpenPrice())
            if ((!BreakEven) && (sl < OrderOpenPrice())) sl = OrderOpenPrice();
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) > sl)
            if (iLow(NULL, CstTimeFrame, CstTrailCandles) < (Bid - ((MarketInfo(Symbol(), MODE_STOPLEVEL)/factor)/10)))
            {
               NewStop = NormalizeDouble(iLow(NULL, CstTimeFrame, CstTrailCandles), Digits);
               //Check that the new stop is > the old. Exit the function if not.
               if (NewStop < OrderStopLoss() || CloseEnough(NewStop, OrderStopLoss()) ) continue;
                modify = true;   
            }
            //if (iLow(NULL, CstTimeFrame, CstTrailCandles) > sl)
         }//if (OrderType == OP_BUY)
   
         if (OrderType() == OP_SELL)
         {
            if ((BreakEven) && (sl > OrderOpenPrice())) continue;
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < OrderOpenPrice())
            if ((!BreakEven) && (sl > OrderOpenPrice())) sl = OrderOpenPrice();
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
            if (iHigh(NULL, CstTimeFrame, CstTrailCandles) > (Ask + ((MarketInfo(Symbol(), MODE_STOPLEVEL)/factor)/10)))
Alert("If I remove this alert, candlesticktrailingstop only works for Buys"); // Why? Why?? WHY???
            {
               NewStop = NormalizeDouble(iHigh(NULL, CstTimeFrame, CstTrailCandles), Digits);
               //Check that the new stop is < the old. Exit the function if not.
               if (NewStop > OrderStopLoss() || CloseEnough(NewStop, OrderStopLoss()) ) continue;
               if (NewStop > OrderOpenPrice() ) continue;
               modify = true;   
            }//if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
         }//if (OrderType() == OP_SELL)
   
         //Move 'hard' stop loss whether hidden or not. Don't want to risk losing a breakeven through disconnect.
         if (modify)
         {
            while (IsTradeContextBusy() ) Sleep(100);
            result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
            if (!result) ReportError(" CandlestickTrailingStop()", slm);
            if (!result) 
            {
               ReportError(" CandlestickTrailingStop()", slm);
               OldCstBars = 0;
            }//if (!result)
          }//if (modify)
      }
   }
   return;
}//End void CandlestickTrailingStop()
I just don't get it... My old eyes, and newbie code skills don't see anything different between the Buy code and the Sell code, (other than swapping the <> around), but the sod just won't work without the Sleep(1); or an alert.

Your help will be greatly appreciated.

Have fun!

Radar =8^)

Try removing line 14, that the only difference.

if (NewStop > OrderOpenPrice() ) continue; <<== No reason why the stop wouldn't be higher then OrderOpenPrice()

if (OrderType() == OP_SELL)
{
if ((BreakEven) && (sl > OrderOpenPrice())) continue;
if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < OrderOpenPrice())
if ((!BreakEven) && (sl > OrderOpenPrice())) sl = OrderOpenPrice();
if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
if (iHigh(NULL, CstTimeFrame, CstTrailCandles) > (Ask + ((MarketInfo(Symbol(), MODE_STOPLEVEL)/factor)/10)))
Alert("If I remove this alert, candlesticktrailingstop only works for Buys"); // Why? Why?? WHY???
{
NewStop = NormalizeDouble(iHigh(NULL, CstTimeFrame, CstTrailCandles), Digits);
//Check that the new stop is < the old. Exit the function if not.
if (NewStop > OrderStopLoss() || CloseEnough(NewStop, OrderStopLoss()) ) continue;
if (NewStop > OrderOpenPrice() ) continue;
modify = true;
}//if (iHigh(NULL, CstTimeFrame, CstTrailCandles) < sl)
}//if (OrderType() == OP_SELL)
Lifesys
Trader
Posts: 126
Joined: Wed Apr 25, 2012 2:05 am
Location: Echuca Victoria. Australia

Re: CandleStickTrailingStop Weirdness

Post by Lifesys »

Hi Radar

Another point is that OrderStopLoss() is not an integer so

Code: Select all

   int sl = OrderStopLoss();
will give you one directional rounding error. Should be

Code: Select all

   double sl = OrderStopLoss();
regards
Paul
Radar
Trader
Posts: 437
Joined: Fri Mar 23, 2012 5:39 pm
Location: Round the bend ;)

Re: CandleStickTrailingStop Weirdness

Post by Radar »

Sorted, thanks :)

MrLong: I tried commenting that line out, but got the same result. You pointed out an error in my thinking... Why was I trying to ensure that sl was at open before moving stops, when I already have BreakEven to do that? Too many late nights, I guess.

Paul: That hit the spot, thanks :) I was so busy looking at the conditionals, that I was ignoring the setup...

It's the weekend, so a looong sleep is in order ;)

Have fun, gentlemen :)

Radar =8^)
Check out my new, (well, old now), manual trade & automatic scale-in manager,
StackManV2
Post Reply

Return to “Coders Hangout”