stringmql4indicatorforexmt4

How do I keep the string value the same when the indicator buffer no longer gives a value?


I've coded a basic Expert Advisor to trigger a trade when the parameters are true. However, in this case the code will never meet all the requirements because the string value gives no value when the indicator buffer doesn't give a value.

What I need help with is to make the string value for saisignal stay the same when triggered by the indicator buffer, after the bar has passed the arrow indicator, so that when the other signals are eventually indicating a trade, it can trigger a trade.

double closeAllTradesThisPair()
{
  for (int i=OrdersTotal();i>=0;i--)
   {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if(OrderSymbol()==Symbol())
    {
     OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,clrNONE);
    }
   }
 }

void OnTick()
{
 double saiup = iCustom( Symbol(), PERIOD_H1, "super-arrow-indicator", 0, 0 );
 double saidn = iCustom( Symbol(), PERIOD_H1, "super-arrow-indicator", 1, 0 );
 double osma1 =   iOsMA( Symbol(), PERIOD_H1, 12, 26, 9, PRICE_OPEN, 1 );
 double osma0 =   iOsMA( Symbol(), PERIOD_H1, 12, 26, 9, PRICE_OPEN, 0 );
 double stup  = iCustom( Symbol(), PERIOD_H1, "super-trend", 0, 0 );
 double stdn  = iCustom( Symbol(), PERIOD_H1, "super-trend", 1, 0 );
 double sar   =    iSAR( Symbol(), PERIOD_H1, 0.02, 0.2, 0 );
 double ma    =     iMA( Symbol(), PERIOD_H1, 20, 0, MODE_SMA, PRICE_CLOSE, 0 );

 string saisignal  = "";
 string osmasignal = "";
 string stsignal   = "";
 string sarsignal  = "";
 string masignal   = "";

 if(saiup < 1000)
  {
    saisignal = "123";
  }
 if(saidn < 1000)
  {
    saisignal = "321";
  }
  
 if(osma1 < osma0)
   {
    osmasignal = "123";
  }
 if(osma1 > osma0)
  {
    osmasignal = "321";
  }

if(stup < 1000)
  {
    stsignal = "123";
  }
if(stdn < 1000)
  {
    stsignal = "321";
  }
 
if(sar < Bid)
  {
    sarsignal = "123";
  }
if(sar > Bid)
  {
    sarsignal = "321";
  }

if(ma < Bid)
  {
    masignal = "123";
  }
if(ma > Bid)
  {
    masignal = "321";
  } 

for(int b=OrdersTotal()-1;b>=0;b--)
  {
    if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
      {
        if(OrderSymbol()==Symbol())
          {
            if(OrderType()==OP_BUY)
              {
                if(OrderStopLoss() < Ask - (150*_Point))
                  {
                    OrderModify(OrderTicket(),OrderOpenPrice(),Ask-(150*_Point),OrderTakeProfit(),0,CLR_NONE);
                  }
              }
            if(OrderType()==OP_SELL)
              {
                if(OrderStopLoss() > Bid + (150*_Point))
                  {
                    OrderModify(OrderTicket(),OrderOpenPrice(),Bid+(150*_Point),OrderTakeProfit(),0,CLR_NONE);
                  }
              }
          }
      }
  }
                   
if(saisignal == "123")
  {
    if(osmasignal == "123")
      {
        if(stsignal == "123")
          {
            if(sarsignal == "123")
              {
                if(masignal == "123")
                  {
                    double buyticket = OrderSend(Symbol(),OP_BUY,0.01,Ask,3,Ask-150*_Point,0,NULL,0,0,CLR_NONE);
                  }
              }
          }
      }
  }

if(saisignal == "321")
  {
    if(osmasignal == "321")
      {
        if(stsignal == "321")
          {
            if(sarsignal == "321")
              {
                if(masignal == "321")
                  {
                    double sellticket = OrderSend(Symbol(),OP_SELL,0.01,Ask,3,Bid+150*_Point,0,NULL,0,0,CLR_NONE);
                  }
              }
          }
      }
  }
Comment("   sai: ",saisignal,"   osma: ",osmasignal,"   st: ",stsignal,"   sar: ",sarsignal,"   ma: ",masignal);
}  

Solution

  • Q : "How do I keep the string value the same...?"

    This problem has a single cause and a pair of available steps for solutions:

    The OnTick(){...} code as-is, per each entry, creates empty strings. This must be replaced anyway.

    But then we have to declare these strings somehow somewhere.

    First option

    Still let them declared inside the "scope" ( the {...} ) of the OnTick(){...}-code-block, but declare them as static string saisignal = ""; // STATIC modifier is key here, as in this case the static makes the compiler to keep the actual value of such declared variable from one OnTick(){...} call to the other ( so never re-declaring and re-storing the initialiser value (here an empty (string)"") each such time.

        #property strict
        ...
        void OnTick(){
             ...
             static string saisignal  = "";
             static string osmasignal = "";
             static string stsignal   = "";
             static string sarsignal  = "";
             static string masignal   = "";
             ...
        }
    

    Second option

    Move such variable declaration onto the "Top-Level" scope (for globally visible variables), which makes compiler reserve a permanent memory location to store and access any such "globally declared/visible" variable(s).

        #property strict
    
        string saisignal  = "";
        string osmasignal = "";
        string stsignal   = "";
        string sarsignal  = "";
        string masignal   = "";
        ...
        void OnTick(){
             ...
        }