How do I make a function that counts bars from the opening time of a position until the current time?

 

Hello everybody, I am planning to make a tool that closes a trade after a number of bars have elapsed, this is my code attempting to do it. Can anybody tell me what's wrong?

#include <Trade\Trade.mqh>
CTrade trade;
bool set_CBB = true;
int CBB = 5;
//+----------------------------------+
void OnInit() {ChartSetInteger(0,CHART_SHOW_GRID,false);}
//+----------------------------------+
void OnTick() {
   
      double ASK = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
      if(PositionsTotal() == 0) {
         trade.Buy(0.10,_Symbol,ASK,ASK-200*_Point,ASK+200*_Point,NULL);
                  
      if(set_CBB == true) {
      
         if(PositionsTotal() > 0) {
            for(int i=PositionsTotal(); i >=0; i--) {
               ulong  position_ticket = PositionGetTicket(i);
               long trade_time = PositionGetInteger(POSITION_TIME);

            int close_bars = Bars(_Symbol,PERIOD_CURRENT,trade_time,TimeCurrent());
            if(close_bars == CBB) trade.PositionClose(position_ticket);
            }
         }
      }
   }
}
 
CopyTime(): If the time of oldest bar >= TimeCurrent()-elapsTime ...
Documentation on MQL5: Timeseries and Indicators Access / CopyTime
Documentation on MQL5: Timeseries and Indicators Access / CopyTime
  • www.mql5.com
CopyTime - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

I would print out each variable and check that everything is getting the right information.

Print("  Position ticket = ",Position_ticket,"     Trade time = ",trade_time," close bars = ",close_bars);

I usually can see what is happening with the code doing this.

 
Andrey Spassov: Can anybody tell me what's wrong?
trade.Buy(0.10,_Symbol,ASK,ASK-200*_Point,ASK+200*_Point,NULL);

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 to a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

  3. 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)

 
Andrey Spassov:

Hello everybody, I am planning to make a tool that closes a trade after a number of bars have elapsed, this is my code attempting to do it. Can anybody tell me what's wrong?

Actually you needed to just move a bracket .

The check for when positions are 0 (to open the first one for the test) was encompassing the entire code , which means your checks run once.

as @Chris Pinter said a print would have revealed that  🙂

#include <Trade\Trade.mqh>
CTrade trade;
bool set_CBB = true;
int CBB = 5;
//+----------------------------------+
void OnInit() {ChartSetInteger(0,CHART_SHOW_GRID,false);}
//+----------------------------------+
void OnTick() {
   
      double ASK = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
      if(PositionsTotal() == 0) {
         trade.Buy(0.10,_Symbol,ASK,0,0,NULL);
        }//this bracket was encompassing all of the code blocking access to your checks   
      if(set_CBB == true) {
      
         if(PositionsTotal() > 0) {
            for(int i=PositionsTotal(); i >=0; i--) {
               ulong  position_ticket = PositionGetTicket(i);
               long trade_time = PositionGetInteger(POSITION_TIME);

            int close_bars = Bars(_Symbol,PERIOD_CURRENT,trade_time,TimeCurrent());
            if(close_bars == CBB) trade.PositionClose(position_ticket);
            Comment("Bars "+IntegerToString(close_bars)+"\nTradeTime["+TimeToString(trade_time,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]\nCurrentTime["+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]");
            }
         }
      }

}

There are still things to consider for instance :

  • What happens if the ea is started and more than 5 bars have elapsed since the trade opened
  • What happens when meta trader 5 fails to deliver the data you want
 
Lorentzos Roussos #:

Actually you needed to just move a bracket .

The check for when positions are 0 (to open the first one for the test) was encompassing the entire code , which means your checks run once.

as @Chris Pinter said a print would have revealed that  🙂

There are still things to consider for instance :

  • What happens if the ea is started and more than 5 bars have elapsed since the trade opened
  • What happens when meta trader 5 fails to deliver the data you want

Thank you all so much for the help. This has resolved my issue, in the future I will be more careful with my code.

The best of regards to you and everyone who helped me out, I wish you all the best!

Reason: