atr trailing stop - page 2

 
user904:

you know what.. the Stop Loss mechanism doesn't seem to be working. It's not closing the position.  What do you think it could be?

Entry is working fine.

Capture a screenshot of the errant trade, with chandelier.mq5 on display.

 
Seng Joo Thio:

Yes, these lines should capture more signals than your original code, but still won't capture all. Example:

The circled bars will give you a close sell and open buy signal without a stop loss... so your 'if' checks must also consider such cases... or even look for additional indicators to complement this...

I've noticed this as well, seems to be a glitch/error?  It happened once before already ...
 
user904:
I've noticed this as well, seems to be a glitch/error?  It happened once before already ...

I wouldn't say that without going deep into the indicator's code.

All I can say is you'll need to check the conditions thoroughly... e.g. when close cuts short_stop, close sell, but (1) don't open buy until long_stop appears... or (2) open a new sell if close cuts short_stop (i.e. trend continuation).

Another alternative is to consider closing with confirmation from other indicator...

 
Seng Joo Thio:

I wouldn't say that without going deep into the indicator's code.

All I can say is you'll need to check the conditions thoroughly... e.g. when close cuts short_stop, close sell, but (1) don't open buy until long_stop appears... or (2) open a new sell if close cuts short_stop (i.e. trend continuation).

Another alternative is to consider closing with confirmation from other indicator...

gotcha.. thanks


this is what I did..


if(PositionSelect(_Symbol) ==false && atr_long_stop[1] > 0)
        {
            int ticket = OrderSend(request,result);
        }
 
Seng Joo Thio:

Capture a screenshot of the errant trade, with chandelier.mq5 on display.

Stop Loss still isn't working.  It doesn't throw ANY errors, just does nothing.

This image shows basically what happens.  Long Stop didn't trigger both times it should have.

And look at that weird red short stop below price, doesnt make sense.

In the other attached image its a short stop that doesnt trigger also.

Basic Principles - Trading Operations - MetaTrader 5 Help
Basic Principles - Trading Operations - MetaTrader 5 Help
  • www.metatrader5.com
is an instruction given to a broker to buy or sell a financial instrument. There are two main types of orders: Market and Pending. In addition, there are special Take Profit and Stop Loss levels. is the commercial exchange (buying or selling) of a financial security. Buying is executed at the demand price (Ask), and Sell is performed at the...
 
user904:

gotcha.. thanks

this is what I did..

Modify it to:

   if(!PositionSelect(_Symbol) && atr_long_stop[1] != EMPTY_VALUE)
   {
      int ticket = OrderSend(request,result);
   }

adding a '!' is the same as having "==false"... and chandelier.mq5 uses EMTPY_VALUE (which equals to DBL_MAX), not 0, when there is no value.

Also, move the entire block after trade.PositionClose() outside the immediate 'if', because now when the opening condition is true, the close condition may be false already.

 
user904:

Stop Loss still isn't working.  It doesn't throw ANY errors, just does nothing.

This image shows basically what happens.  Long Stop didn't trigger both times it should have.

And look at that weird red short stop below price, doesnt make sense.

In the other attached image its a short stop that doesnt trigger also.

Check my reply above... then modify your code and see if these error still appear.

If they do, I need to see your latest code to be sure of what went wrong.

 
Seng Joo Thio:

Modify it to:

adding a '!' is the same as having "==false"... and chandelier.mq5 uses EMTPY_VALUE (which equals to DBL_MAX), not 0, when there is no value.

Also, move the entire block after trade.PositionClose() outside the immediate 'if', because now when the opening condition is true, the close condition may be false already.

I'm sorry not exactly sure what you meant at the end.

This is the whole EA code:

#include <Trade\Trade.mqh>
//--- object of class CTrade
CTrade trade;

// expert advisor ATR & Volatility trailing stop crossover


// timeframe input
input ENUM_TIMEFRAMES TF = PERIOD_D1; // Timeframe to work on


// indicator inputs
input int EA_magic = 12345; // EA magic number
input int ATR_period = 14; // ATR length
input int ATR_stop_multiplier = 2; // ATR stop multiplier
input int ATR_stop_multiplier2 = 3; // ATR stop multiplier 2
input int MA_period = 20;   // filtering MA period
input ENUM_TIMEFRAMES MA_resolution = PERIOD_D1; // MA resolution (daily)

// account risk inputs
//input double account_risk_pcnt = 1; // whole account risk in %
//input double take_profit_pcnt = 5; // take profit in %
input double Lot = 0.01; // lots to trade

// global variables
int hATR_stop, hMA; // handles for indicator functions

double atr_long_stop[], atr_short_stop[], ma[];    // dynamic arrays for atr_stop and filtering moving average
double last_close, previous_close;   // variable to store candle close and previous candle close
int STOP, TP;   // variables for stop and take profit


int OnInit()
{
    hATR_stop = iCustom(NULL,
                        0,
                        "chandelier",
                        ATR_period, 
                        ATR_stop_multiplier, 
                        ATR_stop_multiplier2, 
                        ATR_period);

    hMA = iMA(NULL,
                MA_resolution,
                MA_period,
                0,
                MODE_SMA,
                PRICE_CLOSE);
    
    if(hATR_stop < 0 || hMA < 0)
    { 
        Alert("Error creating handles for indicators - error: ", GetLastError(),"!!");
    }

   return(INIT_SUCCEEDED);
}


void OnDeinit(const int reason)
{
    IndicatorRelease(hATR_stop);
    IndicatorRelease(hMA);
    Alert("EA Deinitialized");
}


void OnTick()
{   

    if(Bars(_Symbol,_Period) < 60)
    {
        Alert("Not enough candles to work with. Exiting.");
        return;
    }

    static datetime Old_Time;
    datetime New_Time[1];
    bool IsNewBar=false;

    int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
    if(copied>0) // ok, the data has been copied successfully
    {
        if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
            IsNewBar=true;   // if it isn't a first call, the new bar has appeared
            Old_Time=New_Time[0];            // saving bar time
        }
    }
    else
    {
        Alert("Error in copying historical times data, error =",GetLastError());
        ResetLastError();
        return;
    }

    //--- EA should only check for new trade if we have a new bar
    if(IsNewBar==false)
    {
        return;
    }
    
    int bars = Bars(_Symbol,_Period);
    if(bars < 60)
    {
        Alert("Not enough candles to work with. Exiting.");
        return;
    }


    MqlTick latest_price;
    MqlTradeRequest request;
    MqlTradeResult result;
    MqlRates rate[];
    ZeroMemory(request);

    ArraySetAsSeries(atr_long_stop, true);
    ArraySetAsSeries(atr_short_stop, true);
    ArraySetAsSeries(rate,true);
    ArraySetAsSeries(ma, true);

    if(!SymbolInfoTick(_Symbol,latest_price))
    {
        Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
        return;
    }

    if(CopyRates(_Symbol,_Period,0,3,rate)<0)
    {
        Alert("Error copying rates/history data - error:",GetLastError(),"!!");
        return;
    }

    if(CopyBuffer(hATR_stop,2,0,3,atr_long_stop)<0 || CopyBuffer(hATR_stop,3,0,3,atr_short_stop)<0)
    {
        Alert("Error copying ATR trailing stop indicator buffers - error:",GetLastError(),"!!");
        return;
    }
    //---- insert copybuffer for moving average
    //----
    //----

    bool long_open=false;
    bool short_open=false;

    if(PositionSelect(_Symbol) ==true)
    {
        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
        {
            long_open = true;
        }
        else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
        {
            short_open = true;
        }
    }

    last_close = rate[1].close;
    previous_close = rate[2].close;


    if(last_close >= atr_short_stop[2] && previous_close <= atr_short_stop[2])
    {
        if(short_open)
        {
            trade.PositionClose(_Symbol);
        }
        // buy long
        request.action = TRADE_ACTION_DEAL;
        request.price = NormalizeDouble(latest_price.ask,_Digits);
        request.symbol = _Symbol;
        request.volume = Lot;
        request.magic = EA_magic;
        request.type = ORDER_TYPE_BUY;
        request.type_filling = ORDER_FILLING_FOK;
        request.deviation = 100;
        // send order
        if(!PositionSelect(_Symbol) && atr_long_stop[1] != EMPTY_VALUE)
        {
            int ticket = OrderSend(request,result);
            if(result.retcode==10009 || result.retcode==10008) //Request is completed or order placed
            {
            Alert("A Buy order has been successfully placed with Ticket#:",result.order,"!!");
            }
            else
            {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();
            return;
            }
        }
    }
    else if(last_close <= atr_long_stop[2] && previous_close >= atr_long_stop[2])
    {
        if(long_open)
        {
            trade.PositionClose(_Symbol);
        }
        // sell short
        request.action = TRADE_ACTION_DEAL;
        request.price = NormalizeDouble(latest_price.bid,_Digits);
        request.symbol = _Symbol;
        request.volume = Lot;
        request.magic = EA_magic;
        request.type = ORDER_TYPE_SELL;
        request.type_filling = ORDER_FILLING_FOK;
        request.deviation = 100;
        //send order if position is closed
        if(!PositionSelect(_Symbol) && atr_short_stop[1] != EMPTY_VALUE)
        {
            
            int ticket = OrderSend(request,result);
            if(result.retcode==10009 || result.retcode==10008) //Request is completed or order placed
            {
            Alert("A Sell order has been successfully placed with Ticket#:",result.order,"!!");
            }
            else
            {
            Alert("The Sell order request could not be completed -error:",GetLastError());
            ResetLastError();
            return;
            }
        }
    }
}
 
user904:
I'm sorry not exactly sure what you meant at the end.

This is the whole EA code:

Ok, try changing this block:

    if(last_close >= atr_short_stop[2] && previous_close <= atr_short_stop[2])
    {
        if(short_open)
        {
            trade.PositionClose(_Symbol);
        }
        // buy long
        request.action = TRADE_ACTION_DEAL;
        request.price = NormalizeDouble(latest_price.ask,_Digits);
        request.symbol = _Symbol;
        request.volume = Lot;
        request.magic = EA_magic;
        request.type = ORDER_TYPE_BUY;
        request.type_filling = ORDER_FILLING_FOK;
        request.deviation = 100;
        // send order
        if(!PositionSelect(_Symbol) && atr_long_stop[1] != EMPTY_VALUE)
        {
            int ticket = OrderSend(request,result);
            if(result.retcode==10009 || result.retcode==10008) //Request is completed or order placed
            {
            Alert("A Buy order has been successfully placed with Ticket#:",result.order,"!!");
            }
            else
            {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();
            return;
            }
        }
    }

into (note the changes in {}, and the highlighted new parts):

    if(last_close >= atr_short_stop[2] && previous_close <= atr_short_stop[2] && atr_short_stop[2] != EMPTY_VALUE)
    {
        if(short_open)
        {
            if (!trade.PositionClose(_Symbol))
                Print("CTrade::PositionClose() method failed. Return code=", trade.ResultRetcode(), ".");
        }
    }

    if(!PositionSelect(_Symbol) && atr_long_stop[2] == EMPTY_VALUE && atr_long_stop[1] != EMPTY_VALUE)
    {
        // buy long
        request.action = TRADE_ACTION_DEAL;
        request.price = NormalizeDouble(latest_price.ask,_Digits);
        request.symbol = _Symbol;
        request.volume = Lot;
        request.magic = EA_magic;
        request.type = ORDER_TYPE_BUY;
        request.type_filling = ORDER_FILLING_FOK;
        request.deviation = 100;
        // send order
        int ticket = OrderSend(request,result);
        if(result.retcode==10009 || result.retcode==10008) //Request is completed or order placed
        {
            Alert("A Buy order has been successfully placed with Ticket#:",result.order,"!!");
        }
        else
        {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();
            return;
        }
    }

Do the same for sell. No more "else" between the outermost "if"s.

 
Seng Joo Thio:

Ok, try changing this block:

into (note the changes in {}, and the highlighted new parts):

Do the same for sell. No more "else" between the outermost "if"s.

I had it work only one time, but still the last order failed with error 4756.

Stop Loss fails with message: "CTrade::PositionClose() method failed. Return code=10006."

Some entries also execute at unusual prices.  See picture.

Why is the buy entry price above the actual candle body?

Stop Loss failed again at 18:30. See 2nd pic.

Basic Principles - Trading Operations - MetaTrader 5 Help
Basic Principles - Trading Operations - MetaTrader 5 Help
  • www.metatrader5.com
is an instruction given to a broker to buy or sell a financial instrument. There are two main types of orders: Market and Pending. In addition, there are special Take Profit and Stop Loss levels. is the commercial exchange (buying or selling) of a financial security. Buying is executed at the demand price (Ask), and Sell is performed at the...
Reason: