How to open one buy deal every 1 candle?

 

Hello





In this picture, i want my expert to open buy position then in the second signal close buy position and open sell position at the same time.


But because of the stop loss on the second signal as you see, the expert close the buy and open sell, and when the price hit stop loss it close sell and reopen sell position too at the same candle!


This cause a multi deals opens in this candle.


so i put this code into my expert to prevent the expert from opening more than position at the same candle:


if(lastTime != iTime(Symbol(), 0, 1)) 
  {
      lastTime = iTime(Symbol(), 0, 1);
  }
  else
  {
      return;
  }


And this cause to prevent me from enter the sell position after closing the buy at the second signal in the picture.


My question is: How do I prevent the expert from opening more than one deal of the same type at the same time?

 
  1. Do you really expect an answer? There are no mind readers here and our crystal balls are cracked. Always post all relevant code (using Code button) or attach the source file.
         How To Ask Questions The Smart Way. (2004)
              Be precise and informative about your problem

    We can't see your broken code.

  2. Most likely, lastTime is not global or static and therefor the return is never executed.

  3. Simplify your code.
    if(lastTime == iTime(Symbol(), 0, 1)) return;
    lastTime = iTime(Symbol(), 0, 1);

 
Ahmed Abd El Aziz:


You may find this helpful - numerous solutions to detecting new candles 

https://www.mql5.com/en/forum/429994

For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()" - How to detect ticks in MT4 timeframes?
For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()" - How to detect ticks in MT4 timeframes?
  • 2022.08.03
  • www.mql5.com
Happy using: detecting a new bar without removing ability to detect tick in multiple timeframe - easy trading strategy - mql4 programming forum #8 (20 21. Only observation was that if you switch timeframes on the chart it can return true on the first tick - i had that issue too
 
William Roeder #:
  1. Do you really expect an answer? There are no mind readers here and our crystal balls are cracked. Always post all relevant code (using Code button) or attach the source file.
         How To Ask Questions The Smart Way. (2004)
              Be precise and informative about your problem

    We can't see your broken code.

  2. Most likely, lastTime is not global or static and therefor the return is never executed.

  3. Simplify your code.

input   int TakeProfit=0;
input   int StopLoss=120;
input int TrailingStop=150;
input   double InpOrderSize=0.1;
input   string InpTradeComment=__FILE__;
input   int InpMagicNumber=10001;

input int RISk=3;
input int SSP=9;
input double AtrRatio=0.375;
bool CloseOpposite;
const string IndicatorName="bykov-trend-nrtr";
const int Handle_Buy=4;
const int Handle_Sell=5;
int Handle;
double BufferBuy[3];
double BufferSell[3];
datetime lastTime = 0;
//      Use CTrade, easier than doing our own coding
#include <Trade\Trade.mqh>
CTrade  *Trade;
int OnInit() {


//      Create a pointer to a ctrade object
Trade=new CTrade();
Trade.SetExpertMagicNumber(InpMagicNumber);
Handle=iCustom(Symbol(),Period(),IndicatorName,RISk,SSP,AtrRatio);
if(Handle==INVALID_HANDLE)
     {
      PrintFormat("Failed",GetLastError());
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason) {
IndicatorRelease(Handle);
}
void OnTick() 
{
//-----------------------------------------------------
int    Account_Number=0;
string Expire_Date="2222.02.22 02:22"; 
if(Expire_Date!=""&&TimeCurrent()>=StringToTime(Expire_Date))
     {
      Comment("Expired!");
      Alert("Expired!");
      return;
     }
     
     if(Account_Number>0&&AccountInfoInteger(ACCOUNT_LOGIN)!=Account_Number)
     {
      Comment("Wrong account number");
      return;
     }
//-----------------------------------------------------
if(lastTime != iTime(Symbol(), 0, 1)) 
  {
      lastTime = iTime(Symbol(), 0, 1);
  }
  else
  {
      return;
  }
int cnt_B = CopyBuffer(Handle,Handle_Buy,0,3,BufferBuy);
int cnt_S = CopyBuffer(Handle,Handle_Sell,0,3,BufferSell);
       
double Previous_Candle_Buy = BufferBuy[1];
double Current_Candle_Buy = BufferBuy[0];
   
double Previous_Candle_Sell = BufferSell[1];
double Current_Candle_Sell = BufferSell[0];
   

double Ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double Bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

double MyPoint=_Point;
if(_Digits==2 || _Digits==5) MyPoint=_Point*10;
double TheStopLoss=0;
double TheTakeProfit=0;
if(TotalOrdersCount()==0 ) 
{
if(Current_Candle_Buy == 0.0 && Previous_Candle_Buy > 0.0)
{
        if(StopLoss>0) TheStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-StopLoss*MyPoint;
        if(TakeProfit>0) TheTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+TakeProfit*MyPoint;
        Trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,InpOrderSize,SymbolInfoDouble(_Symbol,SYMBOL_ASK),TheStopLoss,TheTakeProfit);
        return;
}
if( Current_Candle_Sell == 0.0 && Previous_Candle_Sell > 0.0)       
{
        if(StopLoss>0) TheStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+StopLoss*MyPoint;
        if(TakeProfit>0) TheTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-TakeProfit*MyPoint;
        Trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,InpOrderSize,SymbolInfoDouble(_Symbol,SYMBOL_BID),TheStopLoss,TheTakeProfit);
        return;
}
 }
   int posTotal=PositionsTotal();
   for(int posIndex=posTotal-1;posIndex>=0;posIndex--)
     {
      ulong ticket=PositionGetTicket(posIndex);
      if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber) 
      {
     if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
              if( Current_Candle_Sell == 0.0 && Previous_Candle_Sell > 0.0) //here is your close buy rule
         {
         Trade.PositionClose(ticket);
         break;
         }
       
         if(TrailingStop>0)  
              {                 
               if(SymbolInfoDouble(_Symbol,SYMBOL_BID)-PositionGetDouble(POSITION_PRICE_OPEN)>MyPoint*TrailingStop)
                 {
                  if(PositionGetDouble(POSITION_SL)<SymbolInfoDouble(_Symbol,SYMBOL_BID)-MyPoint*TrailingStop)
                    {
                    Trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_BID)-MyPoint*TrailingStop,PositionGetDouble(POSITION_TP));
                     return;
                    }
                 }
              }
        }
      
       if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
              if( Current_Candle_Buy == 0.0 && Previous_Candle_Buy > 0.0) // here is your close sell rule
         {
         Trade.PositionClose(ticket);
         break;
         }
          if(TrailingStop>0)  
              {                 
               if(PositionGetDouble(POSITION_PRICE_OPEN)-SymbolInfoDouble(_Symbol,SYMBOL_ASK)>MyPoint*TrailingStop)
                 {
                  if(PositionGetDouble(POSITION_SL)>SymbolInfoDouble(_Symbol,SYMBOL_ASK)+MyPoint*TrailingStop)
                    {
                    Trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_ASK)+MyPoint*TrailingStop,PositionGetDouble(POSITION_TP));
                     return;
                    }
                 }
              }
        }
      }
     }  
    return;
}
     
//      true/false has the bar changed
bool    NewBar() {

        static datetime priorTime       =       0;
        datetime                                currentTime     =       iTime(Symbol(), Period(), 0);
        bool                                    result          =       (currentTime!=priorTime);
        priorTime                                                       =       currentTime;
        return(result);
}

//      Close all trades of the specified type - for strategies that call for closing the opposite side
void    CloseAll(ENUM_POSITION_TYPE positionType) {
        int     cnt     =       PositionsTotal();
        for (int i = cnt-1; i>=0; i--) {
                ulong   ticket  =       PositionGetTicket(i);
                if (ticket>0) {
                        if (PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber && PositionGetInteger(POSITION_TYPE)==positionType) {
                                Trade.PositionClose(ticket);
                        }
                }
        }
}

//      Simple function to open a new order
int     OrderOpen(ENUM_ORDER_TYPE orderType, double stopLoss, double takeProfit) {

        double  openPrice;
        double  StopLossPrice;
        double  TakeProfitPrice;

//      Calculate the open price, take profit and stop loss prices based on the order type      
        if (orderType==ORDER_TYPE_BUY) {
                openPrice                       =       NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), Digits());
                StopLossPrice           =       (StopLoss==0.0) ? 0.0 : NormalizeDouble(openPrice - StopLoss, Digits());
                TakeProfitPrice =       (TakeProfit==0.0) ? 0.0 : NormalizeDouble(openPrice + TakeProfit, Digits());
        } else if (orderType==ORDER_TYPE_SELL) {
                openPrice                       =       NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), Digits());
                StopLossPrice           =       (StopLoss==0.0) ? 0.0 : NormalizeDouble(openPrice + StopLoss, Digits());
                TakeProfitPrice =       (TakeProfit==0.0) ? 0.0 : NormalizeDouble(openPrice - TakeProfit, Digits());
        } else {
//      This function only works with type buy or sell
                return(-1);
        }
        Trade.PositionOpen(Symbol(), orderType, InpOrderSize, openPrice, StopLossPrice, TakeProfitPrice, InpTradeComment);
        return((int)Trade.ResultOrder());
}


int TotalOrdersCount()
{
  int result=0;
  int posTotal=PositionsTotal();
   for(int posIndex=posTotal-1;posIndex>=0;posIndex--)
     {
      ulong ticket=PositionGetTicket(posIndex);
      if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber) result++;
     }  
  return (result);
}



This is the full code

 
  1. When I said "always post all relevant code," that includes the indicator (or a link to it.)

  2. if(Current_Candle_Buy == 0.0 && Previous_Candle_Buy > 0.0)

    Why are you trying to buy when there is no buy signal (after the starred bar, instead of on)?

  3. Where is your code to close sell orders before you buy. (after you already tried to open a buy.)

  4.         if(StopLoss>0) TheStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-StopLoss*MyPoint;
            if(TakeProfit>0) TheTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+TakeProfit*MyPoint;

    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, but average maximum spread = 134 (your broker will be similar).

Reason: