Разместите заказ на покупку в другом периоде от H1 до M5.

 
Всем привет,

Следующий код у меня не работает. Я хочу, чтобы при обнаружении пересечения двух скользящих средних H1 я изменил период с помощью ChartSetSymbolPeriod на M5, разместил заказ на покупку (orderSend) и закрыл покупку (orderClose или trade). PositionClose) когда я обнаруживаю пересечение двух скользящих средних на M5, я знаю, что функция ChartSetSymbolPeriod выполняет смену периода асинхронно, правильно ли я это использую? Должен ли я сделать это с помощью ChartSetSymbolPeriod или другим способом? Получается, я не знаю, почему он у меня не работает, он никогда не входит в состояние скользящих средних на периоде М5:

#property copyright "ATILA"
#property link      ""

#include <Trade/trade.mqh>

int takeProfit = 200;
int stopLoss = 100;
CTrade trade;
datetime openTimeBuy = 0;
datetime verticalLines[];
// H1
int maH1_period10, maH1_period20, maH1_period200;
double maH1_period10_Array[], maH1_period20_Array[], maH1_period200_Array[];
// M5
int maM5_period20, maM5_period50;
double maM5_period20_Array[], maM5_period50_Array[];

// Variables globales
MqlRates velasH1[];
MqlRates velasM5[];

int candleCount = 0;

double takeProfitLevel = 0.0; // Nivel de Take Profit

// Declarar una variable para rastrear el estado de la orden
bool isOrderOpen = false;


int OnInit()
{
   ChartSetInteger(0, CHART_SHOW_GRID, false);
   ChartSetInteger(0, CHART_MODE, CHART_CANDLES);
   ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack);
   ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrWhite);
   ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrWhite);
   ChartSetInteger(0, CHART_COLOR_CHART_UP, clrWhite);
   ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrRed);
   ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrRed);
   ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, clrGold);
   ChartSetInteger(0, CHART_SHOW_VOLUMES, false);
   
   // H1
   maH1_period10 = iMA(_Symbol, PERIOD_H1, 10, 0, MODE_SMA, PRICE_CLOSE);
   maH1_period20 = iMA(_Symbol, PERIOD_H1, 20, 0, MODE_SMA, PRICE_CLOSE);
   maH1_period200 = iMA(_Symbol, PERIOD_H1, 200, 0, MODE_SMA, PRICE_CLOSE);
   
   //M15
   maM5_period20 = iMA(_Symbol, PERIOD_M5, 20, 0, MODE_SMA, PRICE_CLOSE);
   maM5_period50 = iMA(_Symbol, PERIOD_M5, 50, 0, MODE_SMA, PRICE_CLOSE);
   
  
   return(INIT_SUCCEEDED);
}

void OnDeinit()
{
}

void OnTick()
{
   // H1
   ArraySetAsSeries(maH1_period10_Array, true);
   ArraySetAsSeries(maH1_period20_Array, true);
   ArraySetAsSeries(maH1_period200_Array, true);
   
   ArraySetAsSeries(velasH1, true);

   CopyBuffer(maH1_period10, 0, 0, 3, maH1_period10_Array);
   CopyBuffer(maH1_period20, 0, 0, 3, maH1_period20_Array);
   CopyBuffer(maH1_period200, 0, 0, 3, maH1_period200_Array);
   
   // M15 
   ArraySetAsSeries(maM5_period20_Array, true);
   ArraySetAsSeries(maM5_period50_Array, true);
   
   //ArraySetAsSeries(velasM5, true);

   CopyBuffer(maM5_period20, 0, 0, 3, maM5_period20_Array);
   CopyBuffer(maM5_period50, 0, 0, 3, maM5_period50_Array);
   
   MACrossOver(maH1_period10_Array, maH1_period20_Array ,maH1_period200_Array);
}

void MACrossOver(double &maH1_period10_Array[], double &maH1_period20_Array[], double &maH1_period200_Array[])
{
   // Tendencia ALCISTA
   if (isBullishTrendThreeMACrossOver(maH1_period10_Array, maH1_period20_Array ,maH1_period200_Array))
   {
         // Verificar si ya hay una orden abierta
      if (!isOrderOpen)
      {
         createVerticalLine("BuyLine" + IntegerToString(ArraySize(verticalLines)), clrBlue, TimeCurrent());
   
         CopyRates(_Symbol, PERIOD_H1, 0, 1, velasH1);
         CopyRates(_Symbol, PERIOD_M5, 0, 12, velasM5);
         
         ChartSetSymbolPeriod(ChartID(), _Symbol, PERIOD_M5);
         
         // Realizar la operación de compra sin establecer TP y SL
         double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double lotSize = 0.01; // Tamaño de lote deseado
         string comment = "BUY";
         int slippage = 3; // Deslizamiento permitido en pips
         
         Buy(123456,_Symbol,lotSize,0,0);
         
         isOrderOpen = true;
         
         if ( maM5_period50_Array[0] > maM5_period20_Array[0] && maM5_period50_Array[1] <= maM5_period20_Array[1] ) {
            
            CloseAllPosition();
            isOrderOpen = false;
            printf("******M5*******");
         }
      }
      
      // Tendencia BAJISTA
   } /*else if (isBearishTrendThreeMACrossOver(maH1_period10_Array, maH1_period20_Array ,maH1_period200_Array)) {
      
                 double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
                 ArrayResize(verticalLines, ArraySize(verticalLines) + 1);
                 verticalLines[ArraySize(verticalLines) - 1] = TimeCurrent();
                 createVerticalLine("SellLine" + IntegerToString(ArraySize(verticalLines)), clrRed, TimeCurrent(), entryPrice);
             }*/
 }

bool isBullishTrendThreeMACrossOver(double &myMovingAverageArray1[], double &myMovingAverageArray2[], double &myMovingAverageArray3[]) 
{

     return (myMovingAverageArray1[0] > myMovingAverageArray2[0] && myMovingAverageArray1[1] <= myMovingAverageArray2[1])
            && (myMovingAverageArray1[0] > myMovingAverageArray3[0] && myMovingAverageArray2[0] > myMovingAverageArray3[0])
            && (myMovingAverageArray1[0] > myMovingAverageArray3[0] && myMovingAverageArray2[0] > myMovingAverageArray3[0]);
            
            
}   

bool isBearishTrendThreeMACrossOver(double &fast[], double &middle[], double &slow[]) 
{
      return (fast[0] <= middle[0] && fast[1] > middle[1])
            && ( (fast[1] < slow[0] && middle[1] < slow[0])
            && (fast[0] < slow[0] && middle[0] < slow[0]));
            
}

void CloseAllPosition()
{
   for( int i = PositionsTotal() - 1; i >= 0; i++ )
   {
      int ticket = PositionGetTicket(i);
      trade.PositionClose(ticket);
   }
}

void createVerticalLine(string name, color clr, datetime time)
{
   double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   ArrayResize(verticalLines, ArraySize(verticalLines) + 1);
   verticalLines[ArraySize(verticalLines) - 1] = TimeCurrent();

   int line = ObjectCreate(0, name, OBJ_VLINE, 0, time, entryPrice);
   if (line != -1)
   {
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 3);
      ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
   }
}

//+------------------------------------------------------------------+
//| Opening Buy position                                             |
//+------------------------------------------------------------------+
void Buy(int magicnumber,string symbol,double lots,double tp,double sl)
{
//--- declare and initialize the trade request and result of trade request
   MqlTradeRequest request {};
   MqlTradeResult  result {};
//--- parameters of request
   request.action    = TRADE_ACTION_DEAL;                     // type of trade operation
   request.symbol    = symbol;                                // symbol
   request.volume    = lots;                                  // volume
   request.type      = ORDER_TYPE_BUY;                        // order type
   request.price     = SymbolInfoDouble(symbol,SYMBOL_ASK);   // price for opening
   request.deviation = 3;                                     // allowed deviation from the price
   request.sl        = sl;                                    // Stop Loss of the position
   request.tp        = tp;                                    // Take Profit of the position
   request.magic     = magicnumber;                           // MagicNumber of the order
//--- send the request
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());       // if unable to send the request, output the error code
//--- information about the operation
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
            MqlDateTime dt_struct;
         datetime dtSer=TimeCurrent(dt_struct);
         string hora = StringFormat("%02d", dt_struct.hour);
         string min = StringFormat("%02d", dt_struct.min);
         string seg = StringFormat("%02d", dt_struct.sec);
               
         printf(" HORA ACTUAL: " + hora + ":" + min + ":" + seg);
}


Кто-нибудь может мне помочь? прилагается (example.png)

Файлы:
example.png  179 kb
 
Mauro Barquinero:
Всем привет,

Следующий код у меня не работает. Я хочу, чтобы при обнаружении пересечения двух скользящих средних H1 я изменил период с помощью ChartSetSymbolPeriod на M5, разместил заказ на покупку (orderSend) и закрыл покупку (orderClose или trade). PositionClose) когда я обнаруживаю пересечение двух скользящих средних на M5, я знаю, что функция ChartSetSymbolPeriod выполняет смену периода асинхронно, правильно ли я это использую? Должен ли я сделать это с помощью ChartSetSymbolPeriod или другим способом? Получается, я не знаю, почему он у меня не работает, он никогда не входит в состояние скользящих средних на периоде М5:


Кто-нибудь может мне помочь? прилагается (example.png)

Период менять не надо, всё может работать без этого.

Надо просто проверять условие закрытия (по MA5) не на том же тике, что и открытие, а на последующих.

 
JRandomTrader #:

Период менять не надо, всё может работать без этого.

Надо просто проверять условие закрытия (по MA5) не на том же тике, что и открытие, а на последующих.

Привет, JRandomTrader!

Спасибо за ответ, я понимаю, но как мне это сделать? Не могли бы вы привести пример того, как это будет выглядеть или что следует заменить в коде? я был бы признателен
 
Mauro Barquinero #:
Привет, JRandomTrader!

Спасибо за ответ, я понимаю, но как мне это сделать? Не могли бы вы привести пример того, как это будет выглядеть или что следует заменить в коде? я был бы признателен

переключение таймфреймов повлечёт полную перезагрузку советника.

вам просто не надо переключать таймфреймы, у вас всё нужное уже есть. 

возможно вам нехватает пары функций:

void OnH1() {
        // new H1 bar is opens
        // actions on it
}
void OnM5() {
        // new M5 bar is opens
        // actions on it
}

и в OnTick или OnTimer добавить их вызов :

datetime timeH1=0;
datetime timeM5=0;

void OnTick() {
    // fragment for call OnM5, OnH1
    datetime bartime=iTime(_Symbol,PERIOD_M5,0);
    if (bartime!=timeM5) {
         timeM5=bartime;
         OnM5();
         bartime=iTime(_Symbol,PERIOD_H1,0);
         if (bartime!=timeH1) {
               timeH1=bartime;
               OnH1();
         }
    }
}
 
Mauro Barquinero #:
Привет, JRandomTrader!

Спасибо за ответ, я понимаю, но как мне это сделать? Не могли бы вы привести пример того, как это будет выглядеть или что следует заменить в коде? я был бы признателен

Например, вынести

         if ( maM5_period50_Array[0] > maM5_period20_Array[0] && maM5_period50_Array[1] <= maM5_period20_Array[1] ) {
            
            CloseAllPosition();
            isOrderOpen = false;
            printf("******M5*******");
         }

из MACrossOver() в отдельную функцию Check_MA5_Close() и вызывать так:

void OnTick()
{
 ...

   if (!isOrderOpen)
   {
      MACrossOver(maH1_period10_Array, maH1_period20_Array ,maH1_period200_Array);
   }
   else
   {
      Check_MA5_Close();
   }
}

И присмотритесь к тому, что Maxim Kuznetsov сказал.

 
JRandomTrader #:

Например, вынести

из MACrossOver() в отдельную функцию Check_MA5_Close() и вызывать так:

И присмотритесь к тому, что Maxim Kuznetsov сказал.

Огромное спасибо JRandomTrader и Maxim Kuznetsov за помощь! Ваша помощь очень ценится.
Maxim Kuznetsov
Maxim Kuznetsov
  • 2023.10.13
  • www.mql5.com
Профиль трейдера
Причина обращения: