Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 1654

 
MakarFX #:

Se conosci un'altra opzione, scrivi...

Puoi aiutare le persone).

Fate tutte le variabili separatamente nell'inite e separatele con un'ulteriore elaborazione (non c'è bisogno di essere pigri).

In seguito, si mettono in parentesi i blocchi e si confrontano le variabili di ritorno.

 
Volodymyr Zubov #:

Fate tutte le variabili separatamente nell'init e separatele con un'ulteriore elaborazione (non c'è bisogno di essere pigri).

In seguito, si mettono in parentesi i blocchi e si confrontano le variabili di ritorno.

Mostra come.
 

In un posto come questo...

Volevo postare l'intero gufo, ma il forum non me lo permette.

Quale frammento volete?

 
Volodymyr Zubov #:

In un posto come questo...

Quale pezzo vuoi?

Chalo...
 
Lo so)
 

Forum sul trading, sistemi di trading automatico e test di strategia

Tutte le domande dei neofiti in MQL4 e MQL5, aiuto e discussione su algoritmi e codici

MakarFX, 2021.10.08 18:43

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(CheckForOpen()==0)
     {
      if(OrderSend(Symbol(),OP_BUY,Lots(),Ask,Slip,Bid-StopLoss*Point,Ask+TakeProfit*Point,"",MagicNumber,0,Blue)) Print("BUY OK");
     }
   if(CheckForOpen()==1)
     {
      if(OrderSend(Symbol(),OP_SELL,Lots(),Bid,Slip,Ask+StopLoss*Point,Bid-TakeProfit*Point,"",MagicNumber,0,Red)) Print("SELL OK");
     }
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
int CheckForOpen() // Открытие ордера по методу Пуриа
  {
   double malw,mas1,mas2,macd;
   int    res=-1, buy=0, sell=0;
   // Считывание параметров индикаторов 3 свечи
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,3);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,3);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,3);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,3);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 2 свечи
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,2);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,2);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,2);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,2);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 1 свечи
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,1);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,1);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,1);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,1);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 0 свечи
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,0);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,0);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,0);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,0);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   
   if(buy ==4) res=0;
   if(sell==4) res=1;
   return(res);
  }

Penso che dovevi avvolgere le chiamate di indicatori identici in una funzione, il codice sarebbe più compatto, e chissà, ora stai usando valori di indicatori per 4 barre, domani per 5 ...

cioè

int SignalByPuria(const int bar)
{
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,bar);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,bar);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,bar);
......
}

A volte ci sono indicatori che non hanno un segnale di trading su una certa barra. Di solito uso l'enum E_CMD{CMD_BUY,CMD_SELL,CMD_NONE};

e poi la firma della funzione "segnale" saràE_CMD SignalByPuria(const int bar) , e il codice EA stesso diventerà qualcosa come questo:

 E_CMD Signal_ind_1(const int bar)
{
....
}

 E_CMD Signal_ind_2(const int bar)
{
....
}

 E_CMD Signal_ind_2(const int bar)
{
....
}

void OnTick()
{
..... 

if(Signal_ind_1 = =CMD_BUY && Signal_ind_2 == CMD_BUY && Signal_ind_3 == CMD_BUY) // открываем ордер на покупку
 else if(Signal_ind_1 = =CMD_SELL && Signal_ind_2 == CMD_SELL && Signal_ind_3 == CMD_SELL) // открываем ордер на продажу

....
}

imho, questo approccio permette di aggiungere rapidamente nuovi segnali di trading al codice EA già scritto

 
Igor Makanu #:

Penso che avresti dovuto avvolgere le stesse chiamate all'indicatore in una funzione, il codice sarebbe stato più compatto, e chissà, ora usi i valori dell'indicatore su 4 barre, domani su 5...

cioè

A volte ci sono indicatori che non hanno un segnale di trading su una certa barra. Di solito uso l'enum E_CMD{CMD_BUY,CMD_SELL,CMD_NONE};

e poi la firma della funzione "segnale" saràE_CMD SignalByPuria(const int bar) , e il codice EA stesso diventerà qualcosa come questo:

imho, questo approccio permette di aggiungere rapidamente nuovi segnali di trading al codice EA già scritto

Grazie Igor, lo prenderò in considerazione)
 

Tornando alla nostra conversazione, ecco la funzione di apertura delle posizioni di mercato per MT4

//+------------------------------------------------------------------+
//|                                                   Zero_Level.mq4 |
//|                                         Copyright © 2007, Xupypr |
//+------------------------------------------------------------------+
// Функция вычисляющая уровни безубытка, на покупку, на продажу с учетом накопленных свопов.
double Zero_Level(string sy, int mn)
  {
   double ZeroLevel=0;
   double BuyLots=0;
   double SellLots=0;
   double BuyProfit=0;
   double SellProfit=0;
   double SellLevel;
   double BuyLevel;

   int Total=OrdersTotal();
   for(int i=Total-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {

         if(OrderSymbol()!=sy)
            continue;
         if(OrderMagicNumber() != mn)
            continue;

         if(OrderType()==OP_BUY)
           {
            BuyLots=BuyLots+OrderLots();
            BuyProfit=BuyProfit+OrderProfit()+OrderCommission()+OrderSwap();
           }
         if(OrderType()==OP_SELL)
           {
            SellLots=SellLots+OrderLots();
            SellProfit=SellProfit+OrderProfit()+OrderCommission()+OrderSwap();
           }
        }
     }

   double TickValue=MarketInfo(sy,MODE_TICKVALUE);
   if(BuyLots>0)
      BuyLevel=NormalizeDouble(MarketInfo(sy,MODE_BID)-(BuyProfit/(TickValue*BuyLots)*MarketInfo(sy,MODE_POINT)),(int)MarketInfo(sy,MODE_DIGITS));
   else
      BuyLevel=0;
   if(SellLots>0)
      SellLevel=NormalizeDouble(MarketInfo(sy,MODE_ASK)+(SellProfit/(TickValue*SellLots)*MarketInfo(sy,MODE_POINT)),(int)MarketInfo(sy,MODE_DIGITS));
   else
      SellLevel=0;
   if(BuyLevel>0)
      ZeroLevel=BuyLevel;
   if(SellLevel>0)
      ZeroLevel=SellLevel;

   return NormalizeDouble(ZeroLevel,_Digits);//Нормализовали полученную цену
  }
//--- End ---
//+---------------------------------------------------------------------------+
//|    Функция открытия рыночной позиции  (c) Boshetunmay 2021                |
//+---------------------------------------------------------------------------+
//|  Параметры:                                                               |
//|    sy - наименование инструмента                                          |
//|    op - операция                                                          |
//|    ll - лот                                                               |
//|    slipp - проскальзывание                                                |
//|    sl - уровень стоп                                                      |
//|    tp - уровень тейк                                                      |
//|    comment - коментарий                                                   |
//|    mn - MagicNumber                                                       |
//|    cl - цвет значка открытия                                              |
//+---------------------------------------------------------------------------+
//  OpenPosition(string symbol,int operation,double volume,int slippage,int stoploss,int takeprofit,string comment,int magic,color);
int OpenPosition(string sy, int op, double ll, int slipp, int sl, int tp, string comment, int mn,color cl)
  {
   if(op == OP_BUY)  // открытие BUY
     {
      // проверяем доступность свободных средств
      if((AccountFreeMarginCheck(sy,OP_BUY,ll)<=0) || (GetLastError()==134))
        {
         Print(sy," ",ll," It is impossible to open the order Buy, not enough money.");
         return(0);
        }
      RefreshRates();

      // открываем ордер OP_BUY
      int ticketbuy = OrderSend(sy,OP_BUY,ll,MarketInfo(sy,MODE_ASK),slipp,0,0,comment,mn,0,cl);
      if(ticketbuy<0)
         Print(sy," OpenPosition. OrderSend Buy fail #",GetLastError());
      else
         Print(sy," OpenPosition. OrderSend Buy successfully");

      Sleep(1000);

      // модифицируем ордер (выставляем тейпрофит и стоплосс)
      if(sl !=0 || tp !=0)
        {
         //--- получим минимальное значение Stop level
         double minstoplevel=MarketInfo(sy,MODE_STOPLEVEL);
         Print("Minimum Stop Level=",minstoplevel," points");
         //--- вычисленные значения цен SL и TP должны быть нормализованы
         double BSLoss = NormalizeDouble(Zero_Level(_Symbol,mn)-(sl+minstoplevel)*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         double BTProfit = NormalizeDouble(Zero_Level(_Symbol,mn)+(tp+minstoplevel)*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         //--- если входящие значения ноль то заменяем цену модификации на ноль
         if(sl == 0)
            BSLoss = 0;
         if(tp == 0)
            BTProfit = 0;

         bool resbuy = OrderModify(ticketbuy,OrderOpenPrice(),BSLoss,BTProfit,0,clrNONE);
         if(!resbuy)
            Print(sy," OpenPosition. OrderModify Buy fail #",GetLastError());
         else
            Print(sy," OpenPosition. OrderModify Buy successfully");
        }
     }

   if(op == OP_SELL)   // открытие Sell
     {
      // проверяем доступность свободных средств
      if((AccountFreeMarginCheck(sy,OP_SELL,ll)<=0) || (GetLastError()==134))
        {
         Print(sy," ",ll," It is impossible to open the order Sell, not enough money.");
         return(0);
        }
      RefreshRates();

      // открываем ордер OP_SELL
      int ticketsell = OrderSend(sy,OP_SELL,ll,MarketInfo(sy,MODE_BID),slipp,0,0,comment,mn,0,cl);
      if(ticketsell<0)
         Print(sy," OpenPosition. OrderSend Sell fail #",GetLastError());
      else
         Print(sy," OpenPosition. OrderSend Sell successfully");

      Sleep(1000);

      // модифицируем ордер (выставляем тейпрофит и стоплосс)
      if(sl !=0 || tp !=0)
        {
         //--- получим минимальное значение Stop level
         double minstoplevel=MarketInfo(sy,MODE_STOPLEVEL);
         Print("Minimum Stop Level=",minstoplevel," points");
         //--- вычисленные значения цен SL и TP должны быть нормализованы
         double SSLoss = NormalizeDouble(Zero_Level(_Symbol,mn)+(sl+minstoplevel)*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         double STProfit = NormalizeDouble(Zero_Level(_Symbol,mn)-(tp+minstoplevel)*MarketInfo(sy,MODE_POINT),(int)MarketInfo(sy,MODE_DIGITS));
         //--- если входящие значения ноль то заменяем цену модификации на ноль
         if(sl == 0)
            SSLoss = 0;
         if(tp == 0)
            STProfit = 0;

         bool ressell = OrderModify(ticketsell,OrderOpenPrice(),SSLoss,STProfit,0,clrNONE);
         if(!ressell)
            Print(sy," OpenPosition. OrderModify Sell fail #",GetLastError());
         else
            Print(sy," OpenPosition. OrderModify Sell successfully");
        }
     }
   return (1);
  }
//--- End ---

Restituisce la bandiera commerciale oggi

//+----------------------------------------------------------------------------+
//|  Описание : Возвращает флаг торгов сегодня.                                |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int isTradeToDay(string sy="", int op=-1, int mn=-1)
  {
   int i, k=OrdersHistoryTotal();

   if(sy=="0")
      sy=_Symbol;
   for(i=0; i<k; i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
         if(OrderSymbol()==sy || sy=="")
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(op<0 || OrderType()==op)
                 {
                  if(mn<0 || OrderMagicNumber()==mn)
                    {
                     if(TimeDay(OrderOpenTime())==Day()
                        &&  TimeMonth(OrderOpenTime())==Month()
                        &&  TimeYear(OrderOpenTime())==Year())
                        return(1);
                    }
                 }
              }
           }
        }
     }
   k=OrdersTotal();
   for(i=0; i<k; i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol()==sy || sy=="")
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(op<0 || OrderType()==op)
                 {
                  if(mn<0 || OrderMagicNumber()==mn)
                    {
                     if(TimeDay(OrderOpenTime())==Day()
                        &&  TimeMonth(OrderOpenTime())==Month()
                        &&  TimeYear(OrderOpenTime())==Year())
                        return(1);
                    }
                 }
              }
           }
        }
     }
   return(0);
  }
//--- End ---

Restituisce il numero di posizioni

//+----------------------------------------------------------------------------+
//|  Описание : Возвращает количество позиций.                                 |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
int NumberOfPositions(string sy="", int op=-1, int mn=-1)
  {
   int i, k=OrdersTotal(), kp=0;

   if(sy=="0")
      sy=_Symbol;
   for(i=0; i<k; i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol()==sy || sy=="")
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(op<0 || OrderType()==op)
                 {
                  if(mn<0 || OrderMagicNumber()==mn)
                     kp++;
                 }
              }
           }
        }
     }
   return(kp);
  }
//--- End ---

Tutto ottimizzato per l'attuale build del terminale.

 
Volodymyr Zubov numero di posizioni

Tutto ottimizzato per l'attuale build del terminale.

Non capisco a cosa servono le dita?
 
MakarFX #:
Non capisco perché ci sono le dita?

Ci sono dita per il fatto che è inopportuno mettere solo OrderSend, e poi non lamentarsi che qualcosa non va. Bisogna sempre cercare gli errori.