Interference of passing value to variables

 

My trading strategy is martingale that if there is deficit and next order is ready to open based on signal. 

I coded some functions for handling buy and sell orders seperately.

Problem 1. if I change the cindition from "if (ticketBuy[position] == -1)"  to "if (orderType == OP_BUY && ticketBuy[position] == -1)", no sell order is opened.

Problem 2. During a 3-year backtest, the function worked fine but at the middle of the back test saying after 2 years, functions handling buy seemed interfering sell side so that no more sell orders were opened and an opened sell order remained unclosed til the end of the back test.

Thanks for your time to look at my coding.

int buyPosition = 0;
int sellPosition = 0;
int ticketBuy[3] = {-1,-1,-1};
int ticketSell[3] = {-1,-1,-1};

void OnTick() {
  
    if (tradingMode == Buy_Only) {
        HandleMartingale(buyPosition, OP_BUY);  // Only handle buy orders
    } else if (tradingMode == Sell_Only) {
        HandleMartingale(sellPosition, OP_SELL);  // Only handle sell orders
    } else if (tradingMode == Buy_and_Sell) {
        HandleMartingale(buyPosition, OP_BUY);    // Handle buy
        HandleMartingale(sellPosition, OP_SELL);  // Handle sell
    }

//+------------------------------------------------------------------+
//| Handle Martingale                                                |
//+------------------------------------------------------------------+
void HandleMartingale(int &position, int orderType) {
    
    switch (position) {
        case 0:
            OpenOrder(lotSize1, sl1, tp1, position, orderType);
            ManageOpenOrders(position, orderType); //for trailing stop and closing order
            break;
        case 1:
            OpenOrder(lotSize2, sl2, tp2, position, orderType);  
            ManageOpenOrders(position, orderType);
            break;
        case 2:
            OpenOrder(lotSize3, sl3, tp3, position, orderType);
            ManageOpenOrders(position, orderType);
            break;
        case 3:
            OpenOrder(lotSize4, sl4, tp4, position, orderType);     
            ManageOpenOrders(position, orderType);
            break;
        default:
            if (orderType == OP_BUY) {
                Print("Maximum OP_BUY martingale layers reached. Continuing with the last layer.");
                position = martingaleLayers - 1;
            } else {
                Print("Maximum OP_SELL martingale layers reached. Continuing with the last layer.");
                position = martingaleLayers - 1;
            }
            break;
    }
}


//+------------------------------------------------------------------+
//| Open Order                                                       |
//+------------------------------------------------------------------+
bool OpenOrder(double lotSize, int sl, int tp, int position, int orderType) {

    if (Time[0] == lastTradeTime) return false;
    
    double initialSl = 0;
    double initialTp = 0;
    
    int macdSignal = MACDSignal();

    if (ticketBuy[position] == -1) {  //<--------------------------change to "if (orderType == OP_BUY && ticketBuy[position] == -1)", no sell order is opened
        if (macdSignal == 0) {
            if (sl > 0) {
                initialSl = Ask - sl * pips;
            }
            if (tp > 0) {
                initialTp = Ask + tp * pips;
            }

            if (Ask - Bid <= spread * pips) {
                ticketBuy[position] = OrderSend(Symbol(), OP_BUY, lotSize, Ask, slippage, initialSl, initialTp, "Buy Order", magicNumber, 0, clrGreen);
                if (ticketBuy[position] < 0) {
                    Print("Error opening buy order: ", GetLastError());
                    return false;
                } else {
                    lastTradeTime = Time[0];
                }
            }
        }
    }

    if (ticketSell[position] == -1) { 
        if (macdSignal == 1) {
            if (sl > 0) {
                initialSl = Bid + sl * pips;
            }
            if (tp > 0) {
                initialTp = Bid - tp * pips;
            }


            if (Ask - Bid <= spread * pips) {
                ticketSell[position] = OrderSend(Symbol(), OP_SELL, lotSize, Bid, slippage, initialSl, initialTp, "Sell Order", magicNumber, 0, clrRed);
                if (ticketSell[position] < 0) {
                    Print("Error opening sell order: ", GetLastError());
                    return false;
                } else {
                    lastTradeTime = Time[0];
                }
            }
        }
    }
    
    if (ticketBuy[position] >= 0 || ticketSell[position] >= 0) {
        return true;
    }

    return false;
}
 
  1. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

  2.                 initialSl = Ask - sl * pips;
                }
                if (tp > 0) {
                    initialTp = Ask + tp * pips;
    

    You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close at a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

    3. Prices (open, SL, and TP) must be a multiple of ticksize. Using Point means code breaks on 4 digit brokers (if any still exists), exotics (e.g. USDZAR where spread is over 500 points), and metals. Compute what a logical PIP is and use that, not points.
                How to manage JPY pairs with parameters? - MQL4 programming forum (2017)
                Slippage defined in index points - Expert Advisors and Automated Trading - MQL5 programming forum (2018)

    4. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

      Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes.
      My GBPJPY shows average spread = 26 points, average maximum spread = 134.
      My EURCHF shows average spread = 18 points, average maximum spread = 106.
      (your broker will be similar).
                Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)