Backtest is ok. Forward test - no executions.

 
Greetings. I can't understand why in backtest environment it executes tens of deals a day and doesn't execute any when I conduct forward test on demo? Any help is appreciated. Thank you in advance.


// Function to place a sell order
bool PlaceSellOrder() {
    double previousLow = iLow(NULL, 0, 1); // Low of the previous candle
    double currentPrice = iLow(NULL, 0, 0); // Current candle low (dynamic)

    // Check if current price is 1 point or more below the previous candle's low
    if (currentPrice < previousLow - Point) {
        double price = currentPrice; // Current price for the sell order
        double sl = price + StopLossPoints * Point;
        double tp = price - TakeProfitPoints * Point;
        
        int ticket = OrderSend(Symbol(), OP_SELL, LotSize, price, Slippage, sl, tp, "", 0, 0, Red);
        if (ticket < 0) {
            LogError("Sell order failed", GetLastError());
            return false;
        }
        return true;
    }
    return false; // No sell order placed if condition is not met
}

// Function to place a buy order
bool PlaceBuyOrder() {
    double previousHigh = iHigh(NULL, 0, 1); // High of the previous candle
    double currentPrice = iHigh(NULL, 0, 0); // Current candle high (dynamic)

    // Check if current price is 1 point or more above the previous candle's high
    if (currentPrice > previousHigh + Point) {
        double price = currentPrice; // Current price for the buy order
        double sl = price - StopLossPoints * Point;
        double tp = price + TakeProfitPoints * Point;

        int ticket = OrderSend(Symbol(), OP_BUY, LotSize, price, Slippage, sl, tp, "", 0, 0, Blue);
        if (ticket < 0) {
            LogError("Buy order failed", GetLastError());
            return false;
        }
        return true;
    }
    return false; // No buy order placed if condition is not met
}

// The main function where the EA logic is executed
void OnTick() {
    // Check if there are open orders
    if (OrdersTotal() > 0) {
        // Manage trailing stop and breakeven if the trade is in profit
        ManageOpenPositions();
        return;
    }

    // Check Sell conditions
    if (CheckSellConditions()) {
        PlaceSellOrder();
    }

    // Check Buy conditions
    if (CheckBuyConditions()) {
        PlaceBuyOrder();
    }
}
 
Update. When I put prints on all the entry conditions - it executed a couple of trades. But then it went silent again. This confused me even more.

P.S. Do I need to post the whole code in order to understand the structure or is it unnecessary?
 
Vadym Dubenko #:
Update. When I put prints on all the entry conditions - it executed a couple of trades. But then it went silent again. This confused me even more.

P.S. Do I need to post the whole code in order to understand the structure or is it unnecessary?

There are two things I see wrong in your code.

1. Your order entry price should use the Bid (sell) or Ask (buy). In your code, you're using iLow as the entry price for OrderSend. FWIW, I use MqlTick/SymbolInfoTick to get the Bid/Ask because the predefined Bid/Ask variables do not work in Tester Mode.

2. When you calculate your own price (e.g., stoploss or takeprofit), you need to normalize the values for OrderSend. Here's a link to help explain how to do that. This also applies to lot size (which the link explains).

Last thing I would do is to use a Print statement to double check that the code is reaching the PlaceSellOrder function and satisfying the conditionals to reach the OrderSend command in your code. This is purely for debugging purposes.

bool PlaceSellOrder() {
    double previousLow = iLow(NULL, 0, 1); // Low of the previous candle
    double currentPrice = iLow(NULL, 0, 0); // Current candle low (dynamic)

    // Check if current price is 1 point or more below the previous candle's low
    if (currentPrice < previousLow - Point) {
        double price = currentPrice; // Current price for the sell order
        double sl = price + StopLossPoints * Point;
        double tp = price - TakeProfitPoints * Point;
        
        int ticket = OrderSend(Symbol(), OP_SELL, LotSize, price, Slippage, sl, tp, "", 0, 0, Red);
        if (ticket < 0) {
            LogError("Sell order failed", GetLastError());
            return false;
        }
        return true;
    }
    return false; // No sell order placed if condition is not met
}
Trailing Bar Entry EA - My first coding attempt in Mql4 and I'd like to be helpful
Trailing Bar Entry EA - My first coding attempt in Mql4 and I'd like to be helpful
  • 2013.08.16
  • [Deleted]
  • www.mql5.com
This is my first coding attempt in mql4, and i'm not an experienced programmer by any means. So, i would really love it if i could get some feedback about my code before i do more coding. Because the problem is not in your code
 
Alexander Martinez #:
1. Your order entry price should use the Bid (sell) or Ask (buy). In your code, you're using iLow as the entry price for OrderSend.

Thank you! When I placed doubles it solved the issue. Thank you so much.


double currentPrice = Bid; // Use the Bid price for sell orders

double currentPrice = Ask; // Use the Ask price for buy orders
 
Vadym Dubenko #:

Thank you! When I placed doubles it solved the issue. Thank you so much.


You're welcome!

I still recommend you use MqlTick because Bid/Ask do not update in Tester Mode (at least for me).

MqlTick tick;
SymbolInfoTick(_Symbol, tick);
tick.bid // use for Sell
tick.ask // use for Buy

And don't forget to normalize your stoploss, takeprofit, and lots.

Take care!

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Price Data Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Price Data Structure
  • www.mql5.com
This is a structure for storing the latest prices of the symbol. It is designed for fast retrieval of the most requested information about current...
 
Alexander Martinez #:
I still recommend you use MqlTick
// Use MqlTick structure to get the latest Bid and Ask prices
MqlTick tick;

// Function to place a sell order using MqlTick for Bid price
bool PlaceSellOrder() {
    // Get the latest tick data
    SymbolInfoTick(_Symbol, tick);
    
    double price = tick.bid; // Use tick.bid for sell orders
    double sl = price + StopLossPoints * Point;
    double tp = price - TakeProfitPoints * Point;
    
    int ticket = OrderSend(Symbol(), OP_SELL, LotSize, price, Slippage, sl, tp, "", 0, 0, Red);
    if (ticket < 0) {
        LogError("Sell order failed", GetLastError());
        return false;
    }
    return true;
}

// Function to place a buy order using MqlTick for Ask price
bool PlaceBuyOrder() {
    // Get the latest tick data
    SymbolInfoTick(_Symbol, tick);

    double price = tick.ask; // Use tick.ask for buy orders
    double sl = price - StopLossPoints * Point;
    double tp = price + TakeProfitPoints * Point;
    
    int ticket = OrderSend(Symbol(), OP_BUY, LotSize, price, Slippage, sl, tp, "", 0, 0, Blue);
    if (ticket < 0) {
        LogError("Buy order failed", GetLastError());
        return false;
    }
    return true;
}
Alexander Martinez #:
And don't forget to normalize your stoploss, takeprofit, and lots.

// External variables that can be set by the trader
extern double TakeProfitPoints = 50;       // Take Profit in points
extern double StopLossPoints = 50;          // Stop Loss in points
extern double BreakevenPoints = 50;         // Points in profit when Stop Loss is moved to Breakeven
extern double TrailStopDistance = 50;       // Trailing Stop distance in points
extern double MinPriceMove = 50;            // Minimum price move in consecutive candles before entering
extern double LotSize = 0.01;                // Fixed lot size
extern int Slippage = 20; // Define slippage (in points)

Is that what you meant or something else?

The EA executes only market orders and as I understood from the link you provided it is not needed to normalize market executions.

 

I've got the idea. Here is updated code. It seems to me that this is what you wanted me to do. Thank you!

// Function to place a sell order using MqlTick for Bid price with normalized price and lots
bool PlaceSellOrder() {
    MqlTick tick;
    SymbolInfoTick(_Symbol, tick); // Get the latest tick data
    
    double price = NormalizePrice(tick.bid); // Normalize Bid price
    double sl = NormalizePrice(price + StopLossPoints * Point); // Normalize Stop Loss
    double tp = NormalizePrice(price - TakeProfitPoints * Point); // Normalize Take Profit
    double lotSize = NormalizeLots(LotSize); // Normalize lot size
    
    if (lotSize == 0) {
        Print("Error: Lot size too small.");
        return false;
    }
    
    int ticket = OrderSend(Symbol(), OP_SELL, lotSize, price, Slippage, sl, tp, "", 0, 0, Red);
    if (ticket < 0) {
        LogError("Sell order failed", GetLastError());
        return false;
    }
    return true;
}

// Function to place a buy order using MqlTick for Ask price with normalized price and lots
bool PlaceBuyOrder() {
    MqlTick tick;
    SymbolInfoTick(_Symbol, tick); // Get the latest tick data
    
    double price = NormalizePrice(tick.ask); // Normalize Ask price
    double sl = NormalizePrice(price - StopLossPoints * Point); // Normalize Stop Loss
    double tp = NormalizePrice(price + TakeProfitPoints * Point); // Normalize Take Profit
    double lotSize = NormalizeLots(LotSize); // Normalize lot size
    
    if (lotSize == 0) {
        Print("Error: Lot size too small.");
        return false;
    }
    
    int ticket = OrderSend(Symbol(), OP_BUY, lotSize, price, Slippage, sl, tp, "", 0, 0, Blue);
    if (ticket < 0) {
        LogError("Buy order failed", GetLastError());
        return false;
    }
    return true;
}
 
Vadym Dubenko #:

I've got the idea. Here is updated code. It seems to me that this is what you wanted me to do. Thank you!

Looks good! The only thing I'd change is to not use NormalizePrice on tick.bid (and tick.ask).

double price = NormalizePrice(tick.bid); // Normalize Bid price

The reason is because the prices that come from the terminal are already normalized; what needs normalizing are prices that you calculate on your own, such as in this example where you calculated your stoploss based off of points:

double sl = NormalizePrice(price + StopLossPoints * Point);

It's simple to remember: did the price come from the terminal (e.g., Close[0], iHigh, Bid, tick.ask, etc)?

* If yes, then you don't need to normalize.
* If not, you should normalize before using it in OrderSend/OrderModify/OrderClose.

Other than that, your code is fine. Take care.

 
Alexander Martinez #:

Looks good! The only thing I'd change is to not use NormalizePrice on tick.bid (and tick.ask).

The reason is because the prices that come from the terminal are already normalized; what needs normalizing are prices that you calculate on your own, such as in this example where you calculated your stoploss based off of points:

It's simple to remember: did the price come from the terminal?

* If yes, then you don't need to normalize.
* If not, you should normalize before using it in OrderSend/OrderModify/OrderClose.

Other than that, your code is fine. Take care.

Thank you! I greatly appreciate your advices and help. I will follow your suggestion.

 
Vadym Dubenko #:

Thank you! I greatly appreciate your advices and help. I will follow your suggestion.

You're welcome, have a great day. :)