Dont allow to change timeframe while EA is attached to a chart.

 

I have an EA that only works on H1 timeframe, is there a way to:


- Automatically change timeframe to H1 when EA is attached succesfully to a chart?

- Disable the abiility to change timeframe while the EA is attached to a chart.


Thank you very much!

 
BeLikeWater: I have an EA that only works on H1 timeframe, is there a way to:

- Automatically change timeframe to H1 when EA is attached succesfully to a chart?
- Disable the abiility to change timeframe while the EA is attached to a chart.

Under normal MQL, the answer is NO to both questions, although with some external WinAPI tricks you could accomplish it, but it would not be very practical to implement!
EDIT: I guess I was wrong, as WHRoeder has pointed out below!

However, you can alter your code so that the EA always uses H1 data irrespective of the time-frame of the chart!

You can accomplish this by either using the ArrayCopyRates() function, in order to have a TimeSeries array of the H1 data, or by using the various functions such as iOpen(), iHigh(), iLow(), iClose(), iTime() with a time-frame selection argument.

 
BeLikeWater:

- Automatically change timeframe to H1 when EA is attached succesfully to a chart?

- Disable the abiility to change timeframe while the EA is attached to a chart.

  1. Yes ChartSetSymbolPeriod - Chart Operations - MQL4 Reference
  2. Can't disable it but you can remember the previous and change back.
    NOT TESTED
       #define  THIS_SYMBOL ""                   ///< Indicates current `_Symbol`.
    enum Uninitialization_Reason{
       UNINIT_PROGRAM,      /**< Expert Advisor terminated its operation by calling
                             * the ExpertRemove() function */
       UNINIT_REMOVE,       ///< Program has been deleted from the chart
       UNINIT_RECOMPILE,    ///< Program has been recompiled
       UNINIT_CHARTCHANGE,  ///< Symbol or chart period has been changed
       UNINIT_CHARTCLOSE,   ///< Chart has been closed
       UNINIT_PARAMETERS,   ///< Input parameters have been changed by a user
       UNINIT_ACCOUNT,      /**< Another account has been activated or reconnection
                             * to the trade server has occurred due to changes in
                             * the account settings.                              */
       UNINIT_TEMPLATE,     ///< A new template has been applied
       UNINIT_INITFAILED,   /**< This value means that OnInit() handler has returned
                             * a nonzero value.                                   */
       UNINIT_CLOSE         /**< Terminal has been closed*/  };
    string            as_string(Uninitialization_Reason reason){
       string UNINIT_XXXX = EnumToString(reason);
       return StringSubstr(UNINIT_XXXX, 7);
    }
    int      Core::on_init(string v){
       if(mPreviousSymbol != THIS_SYMBOL){             // Init due to chart change,
                                                       // WITH open orders.
          if(mPreviousSymbol != _Symbol){              // Symbol changed: UNDO!
             Alert(StringFormat("Chart change to %s with ticket open on %s",
                               _Symbol, mPreviousSymbol) );
             ChartSetSymbolPeriod(0, mPreviousSymbol, _Period);
             return   INIT_SUCCEEDED;
          }
          mPreviousSymbol = THIS_SYMBOL;               // Period changed: no problem
       }
       :
    }
    void     Core::on_deinit(Uninitialization_Reason reason){
       switch(reason){
       case  UNINIT_RECOMPILE:
       case  UNINIT_PARAMETERS:
       case  UNINIT_TEMPLATE:
          break;   // Benign, will return to the same chart.
       case  UNINIT_CHARTCHANGE:
                   // Benign, will return to the same symbol, different period.
                   // Bad, will return to a different symbol, same period!
          if(mPreviousSymbol == THIS_SYMBOL)  // Not already bad case undoing.
             mPreviousSymbol = _Symbol;       // Remember for possible bad.
          break;                              // No alert for benign case.
       default:
          Alert(StringFormat("Uninitialize (%s) with open tickets on %s",
                             as_string(reason), _Symbol));
          break;
       }  // switch
    
    NOT TESTED
 
William Roeder #:
  1. Yes ChartSetSymbolPeriod - Chart Operations - MQL4 Reference
  2. Can't disable it but you can remember the previous and change back.
    NOT TESTEDNOT TESTED

Hello guys.

I know that is a very old topic, but I am looking for something exactly like this, because I am using a dynamic magicnumber creation and to avoid ghost operations I have to disable the symbol and period changes while exists an open position. I have checked the code above but I don't know where exactly write it in (OnInit, OnDeinit, etc.) and what is exactly the function "as_string" because this function is not documented.

Have someone made it work in mql5?

 
  1. b2tradingclub #: and what is exactly the function "as_string" because this function is not documented.
    #2.2
  2. b2tradingclub #: , because I am using a dynamic magicnumber creation 

    You create your own problem.

    Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number/symbol filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)
              PositionClose is not working - MQL5 programming forum (2020)
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles (2006)
              Orders, Positions and Deals in MetaTrader 5 - MQL5 Articles (2011)
              Limit one open buy/sell position at a time - General - MQL5 programming forum (2022)

    You need one Magic Number for each symbol/timeframe/strategy. Trade current timeframe, one strategy, and filter by symbol requires one MN.

 
William Roeder #:
  1. #2.2
  2. You create your own problem.

    Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number/symbol filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)
              PositionClose is not working - MQL5 programming forum (2020)
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles (2006)
              Orders, Positions and Deals in MetaTrader 5 - MQL5 Articles (2011)
              Limit one open buy/sell position at a time - General - MQL5 programming forum (2022)

    You need one Magic Number for each symbol/timeframe/strategy. Trade current timeframe, one strategy, and filter by symbol requires one MN.


I know that I have created my own problem, but was the solution that I have found to solve another problem when using Netting accounts... eg. If I run an strategy to buy only in one symbol+timeframe, I can use the same EA to sell only in the same symbol but in a different timeframe. Using a specific magicnumber for symbol+period+strategy_type(buysell,buyonly,sellonly).

The EA will have it's own TraderPad, what will allow me to send manual orders as the EA.

For manual trades using the same symbol+timeframe, I will have to use another TraderPad using another magic number with a fixed value that will help me to identify manual trades.

The problem now is disable symbol/period changes when exists an position, because there is no way to close that position if the symbol/period changes.

Your solution above apparently will solve my problem, but the as_string is missing in the code and I don't know what exactly that function do to try to test it.

 
b2tradingclub #:


I know that I have created my own problem, but was the solution that I have found to solve another problem when using Netting accounts... eg. If I run an strategy to buy only in one symbol+timeframe, I can use the same EA to sell only in the same symbol but in a different timeframe. Using a specific magicnumber for symbol+period+strategy_type(buysell,buyonly,sellonly).

The EA will have it's own TraderPad, what will allow me to send manual orders as the EA.

For manual trades using the same symbol+timeframe, I will have to use another TraderPad using another magic number with a fixed value that will help me to identify manual trades.

The problem now is disable symbol/period changes when exists an position, because there is no way to close that position if the symbol/period changes.

Your solution above apparently will solve my problem, but the as_string is missing in the code and I don't know what exactly that function do to try to test it.

Hey William, thank you for the example above. Apparently your code solve the situation. I successfully modified your code to work here. Follow the code to help someone in the future!


   // Init due to chart/perid change WITH open orders.
   int OnInitChanges()
   {
      if (mPreviousSymbol != (string)THIS_SYMBOL && mPreviousPeriod == (ENUM_TIMEFRAMES)THIS_PERIOD)          
      {
         if (mPreviousSymbol != GetSymbol()) // Symbol changed: UNDO!
         {
            Alert(StringFormat("Chart change to %s with ticket open on %s",
                           GetSymbol(), mPreviousSymbol));
            ChartSetSymbolPeriod(0, mPreviousSymbol, GetPeriod());

            return (INIT_SUCCEEDED);
         }

         mPreviousSymbol = THIS_SYMBOL; // Period changed: no problem
      }

      if (mPreviousSymbol == (string)THIS_SYMBOL && mPreviousPeriod != (ENUM_TIMEFRAMES)THIS_PERIOD)
      {
         if (mPreviousPeriod != GetPeriod()) // Symbol changed: UNDO!
         {
            Alert(StringFormat("Chart change to %s with ticket open on %s",
                           GetSymbol(), mPreviousSymbol));
            ChartSetSymbolPeriod(0, GetSymbol(), mPreviousPeriod);

            return (INIT_SUCCEEDED);
         }

         mPreviousPeriod = (ENUM_TIMEFRAMES)THIS_PERIOD; // Period changed: no problem
      }
      
      return (INIT_SUCCEEDED);
   }

   void OnDeinitChanges(Uninitialization_Reason reason)
   {
      switch(reason)
      {
         case  UNINIT_RECOMPILE:
         case  UNINIT_PARAMETERS:
         case  UNINIT_TEMPLATE:
            break;   // Benign, will return to the same chart.
         case  UNINIT_CHARTCHANGE:
                     // Benign, will return to the same symbol, different period.
                     // Bad, will return to a different symbol, same period!
            if (mPreviousSymbol == THIS_SYMBOL) // Not already bad case undoing.
               mPreviousSymbol = GetSymbol();   // Remember for possible bad.
            if (mPreviousPeriod == (ENUM_TIMEFRAMES)THIS_PERIOD)  // Not already bad case undoing.
               mPreviousPeriod = GetPeriod();   // Remember for possible bad.
            break;                              // No alert for benign case.
         default:
            Alert(StringFormat("Uninitialize (%s) with open tickets on %s",
                               EnumAsString(reason), GetSymbol()));
            break;
      }  // switch
   }

#define THIS_SYMBOL "" ///< Indicates current `_Symbol` when symbol changes.
#define THIS_PERIOD "" ///< Indicates current `_Period` when period changes.

enum Uninitialization_Reason
{
   UNINIT_PROGRAM,      /**< Expert Advisor terminated its operation by calling
                         * the ExpertRemove() function */
   UNINIT_REMOVE,       ///< Program has been deleted from the chart
   UNINIT_RECOMPILE,    ///< Program has been recompiled
   UNINIT_CHARTCHANGE,  ///< Symbol or chart period has been changed
   UNINIT_CHARTCLOSE,   ///< Chart has been closed
   UNINIT_PARAMETERS,   ///< Input parameters have been changed by a user
   UNINIT_ACCOUNT,      /**< Another account has been activated or reconnection
                         * to the trade server has occurred due to changes in
                         * the account settings.                              */
   UNINIT_TEMPLATE,     ///< A new template has been applied
   UNINIT_INITFAILED,   /**< This value means that OnInit() handler has returned
                         * a nonzero value.                                   */
   UNINIT_CLOSE         /**< Terminal has been closed*/
};

        string EnumAsString(Uninitialization_Reason reason)
        {
      string UNINIT_XXXX = EnumToString(reason);
      return StringSubstr(UNINIT_XXXX, 7);
        }

Basically you have to call OnInitChanges and OnInitChanges() in your OnInit() and call OnDeinitChanges((Uninitialization_Reason) reason) in your OnDeinit() functions.
It's working for me.
Reason: