EA stops after 7 trades? Also not closing orders properly

 

Hi All,

While I'm not entirely new to coding I'm no pro either. I'm trying to code an EA that trades based on a basic Donchian Channel strategy, where I place a buy order when the price closes above the upper band, and closes that order when it touches the middle band. The short will open when the price is below the lower band, and close when the price touches the middle band. And we don't open any new orders until the previously opened position is closed. 

The EA currently only places 7 trades and then just stops. It closes them improperly and I don't believe its respecting the stop losses.

Here is my code. Any tips would be greatly appreciated!

//+------------------------------------------------------------------+
//|                                                 Donchian-Trader.mq4 |
//+------------------------------------------------------------------+

#property version "1.00"
#property strict

// Declare external variables.
extern int MinPipLimit = 0;
extern int TakeProfit = 40;
extern int StopLoss = 40;
extern double Lots = 1;
extern int Magic = 1;
extern bool ECNExecution = false;
extern bool UseTrailingSL = false;
extern int TrailValue = 40;
extern bool AutoAdjustTo5Digits = false;
extern int DonchianBarsToCount = 20;
extern int Slippage;

double MyPoint;

double dUpper = iCustom(NULL, 0, "DonchianChannels", 20, 0, 0);
double dMiddle = iCustom(NULL, 0, "DonchianChannels", 20, 1, 0);
double dLower = iCustom(NULL, 0, "DonchianChannels", 20, 2, 0);

//On init, lets adjust to a 5 digit broker, if necessary
void OnInit()
{
    SetMyPoint();
}

void OnTick()
{
    static bool IsFirstTick = true;
    static bool ReadyForNewOrder = true;
    static int ticket = 0;
    string comment;

    //Order Execution
    comment = GetDateAndTime();

    //FindTicket makes sure that the EA will pick up its orders
    //even if it is relaunched
    ticket = FindTicket(Magic);
    bool res;
    res = OrderSelect(ticket, SELECT_BY_TICKET);

    //If an open position exists, lets see if we can close it.
    if (res == true)
    {
        if (OrderCloseTime() == 0)
        {
            //No new orders until the open position is closed
            ReadyForNewOrder = false;

            // Select the open order
            int SelectedOrder = OrderSelect(ticket, SELECT_BY_TICKET);

            //Lets get our long positions and do something.
            if (OrderType() == OP_BUY)
            {
                //Long order should close when the price is less than or equal to the middle Donchian band.
                if (Open[0] <= dMiddle)
                {
                    //Lets close the order and store the result in a boolean.
                    bool res2;
                    res2 = OrderClose(ticket, OrderLots(), OrderClosePrice(), 10);
                    if (res2)
                    {
                        ReadyForNewOrder = true;
                    }
                }
            }
            //Lets get our short position and do something.
            else if (OrderType() == OP_SELL)
            {
                //Short order should close when the price is greater than or equal to the middle Donchian band
                if (Open[0] >= dMiddle)
                {
                    //Lets close the order and store the result in a boolean.
                    bool res2;
                    res2 = OrderClose(ticket, OrderLots(), OrderClosePrice(), 10);
                    if (res2)
                    {
                        ReadyForNewOrder = true;
                    }
                }
            }
        }
    }
    //When all our open positions are closed, lets start a new order.
    if (ReadyForNewOrder == true)
    {
        //Open a long position when the price is greater than or equal to the upper band.
        if (Open[0] >= dUpper)
        {
            ticket = MarketOrderSend(Symbol(), OP_BUY, Lots, ND(Ask), 10 * int(MyPoint / Point()), ND(Bid - StopLoss * MyPoint), ND(Bid + TakeProfit * MyPoint), "Set by SimpleSystem", Magic);
            //Check if the order was sent successfully
            if (ticket < 0)
            {
                comment = comment + " " + "Error Sending BUY Order";
            }
            else
            {
                comment = comment + " " + "BUY Order Executed Succesfuly";
            }
        }
        //Open a short position when the price is less than or equal to the lower band.
        else if (Open[0] <= dLower)
        {
            ticket = MarketOrderSend(Symbol(), OP_SELL, Lots, ND(Ask), 10 * int(MyPoint / Point()), ND(Bid - StopLoss * MyPoint), ND(Bid + TakeProfit * MyPoint), "Set by SimpleSystem", Magic);
            if (ticket < 0)
            {
                comment = comment + " " + "Error Sending SELL Order";
            }
            else
            {
                comment = comment + " " + "SELL Order Executed Succesfully";
            }
        }
    }
    //Print results
    Comment(comment);
    Print(comment);

    //execute trailing stop - this has to be done on every tick
    if (UseTrailingSL == true)
    {
        //FindTicket makes sure that the EA will pick up its orders
        //even if it is relaunched
        int ticket_trailing = FindTicket(Magic);

        if (ticket_trailing > 0)
        {
            TrailingStop(ticket_trailing);
        }
    }
}

/*
   -------------------------------
         Auxiliary Functions     
   -------------------------------
*/

int FindTicket(int M)
{
    int ret = 0;

    for (int i = OrdersTotal() - 1; i >= 0; i--)
    {
        bool res;
        res = OrderSelect(i, SELECT_BY_POS);
        if (res == true)
        {
            if (OrderMagicNumber() == M)
            {
                ret = OrderTicket();
                break;
            }
        }
    }

    return (ret);
}

string GetDateAndTime()
{
    return (string(Year()) + "-" + StringFormat("%02d", Month()) + "-" + StringFormat("%02d", Day()) + " " + StringFormat("%02d", Hour()) + ":" + StringFormat("%02d", Minute()));
}

int MarketOrderSend(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic)
{
    int ticket;

    if (ECNExecution == false)
    {
        ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic);
        if (ticket <= 0)
            Alert("OrderSend Error: ", GetLastError());
        return (ticket);
    }
    else
    {
        ticket = OrderSend(symbol, cmd, volume, price, slippage, 0, 0, comment, magic);
        if (ticket <= 0)
            Alert("OrderSend Error: ", GetLastError());
        else
        {
            bool res = OrderModify(ticket, OrderOpenPrice(), stoploss, takeprofit, 0);

            if (!res)
                Alert("!!! ORDER #", ticket, " HAS NO STOPLOSS AND TAKEPROFIT --- ORDER MODIFY ERROR: ", GetLastError());
        }
        return (ticket);
    }
}

void TrailingStop(int ticket)
{
    bool res;
    res = OrderSelect(ticket, SELECT_BY_TICKET);

    if (res == true)
    {
        if (OrderType() == OP_BUY)
        {
            if (Bid - OrderStopLoss() > TrailValue * MyPoint) //adjust stop loss if it is too far
            {
                res = OrderModify(OrderTicket(), OrderOpenPrice(), ND(Bid - TrailValue * MyPoint), OrderTakeProfit(), 0);
                if (!res)
                {
                    Alert("TrailingStop OrderModify Error: ", GetLastError());
                }
            }
        }

        if (OrderType() == OP_SELL)
        {
            if (OrderStopLoss() - Ask > TrailValue * MyPoint) //adjust stop loss if it is too far
            {
                res = OrderModify(OrderTicket(), OrderOpenPrice(), ND(Ask + TrailValue * MyPoint), OrderTakeProfit(), 0);
                if (!res)
                {
                    Alert("TrailingStop OrderModify Error: ", GetLastError());
                }
            }
        }
    }
}

void SetMyPoint()
{
    MyPoint = Point();
    if (AutoAdjustTo5Digits == true && (Digits() == 3 || Digits() == 5))
    {
        Alert("Digits=", Digits(), " Broker quotes given in 5-digit mode. Old values of SL, TP and slippage will be multiplied by 10");
        MyPoint = Point() * 10;
    }
}

double ND(double val)
{
    return (NormalizeDouble(val, Digits()));
}
Files:
Capture.PNG  105 kb
Capture2.PNG  67 kb
Reason: