Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 1546

 
MakarFX:
Haben Sie einen EA, der manuell platzierte Aufträge unterstützt?
Ja. Ich platziere die Pending Orders manuell oder eröffne einfach einen Handel, und dann funktioniert der Expert Advisor.
 
SGarnov:
Ich habe versucht, es einzufügen, aber es lässt sich nicht kompilieren. Der gesamte Code, wenn nötig, werde ich einen Screenshot der Kompilierung setzen. Ich denke, es kann ein weiteres Problem, mein TP ist in Bezug auf STOP durch Koeffizient (externe Variable), vielleicht kann es geändert werden, um manuelle Einstellung und es wird einfacher für EA zu ergänzen?

Die Funktion

  double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }

aus dem globalen Bereich. magic=0 für die Kompilierung.

magic=0

	          
 
Galim_V:

Die Funktion

aus dem globalen Bereich, entfernen Sie magic=0 für die Kompilierung.

Entfernt, keine Kompilierungsfehler, nur 1 Warnung erscheint in der dritten Funktionszeile in der Spalte tp=0 mit dem Hören auf die externe Variable int tp=0. Ich verstehe nicht ganz, was dem Programmierer nicht gefällt. Alle Codes sind beigefügt, wenn Sie nicht schwer zu korrigieren sind, ist die Wahrheit irgendwo in der Nähe.

input int takeProfitC = 2;// Коэффициент Take Profit
input int stop_loss = 100;//Уровень Stop Loss
input int stop_count = 2;//Количество Stop Loss
input double lots = 0.01;//Лоты
input int slippage = 30;//Проскальзывание
input int datePeriod = 48;// Время удержания при SL


int tp = 0;
int tpc = 0;
double tp_price_old = 777;
int stopLossCount = 0;
datetime startOrder = 0;
int pending_ticket = 0;
int lastMagic = 0;
bool isLimitOn = false;
bool isStart = True;
datetime startTime = 0;
bool isFinal = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//
   //OrderSend(Symbol(), OP_SELL, 0.01, 0.76228, 300, 0, 0);
   //OrderSend(Symbol(), OP_SELLSTOP, 0.01, 0.77057, 300, 0, 0);
   //OrderSend(Symbol(), OP_BUYSTOP, 0.01, 0.76928, 300, 0, 0);
   tp = stop_loss * takeProfitC;
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
//Comment("StopCount: " + stopLossCount + "\n" + "CurrentStopC: " + stop_count);
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderSymbol() == Symbol()) {
         int magic = OrderMagicNumber();
            if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderOpenTime()) {
               int ticket = OrderTicket();
               if(!findPending(ticket)) {
                  if(OrderSelect(ticket, SELECT_BY_TICKET) && (((TimeCurrent() <= (startTime + datePeriod * 3600))) || isStart)) {
                     if(OrderType() == OP_BUY) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() - Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                           if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              tp_price_old = tp_price;
                              stopLossCount++;                         
                           }
                        }
                     } else if(OrderType() == OP_SELL) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() + Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                          if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              stopLossCount++;
                              tp_price_old = tp_price;  
                          }
                        }
                     }
                  }
               }
         }
         if(startTime > 0 && (TimeCurrent() >= (startTime + datePeriod * 3600))){
            deletePending(lastMagic);
            isFinal = true;
         }
            
         if(lastMagic != 0 && !IsSell() && !IsBuy() && magic == lastMagic) {
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            deletePending(lastMagic);
            isStart = true;
            }
         }
     }
   }
   if((startTime > 0 || isFinal) && !IsSell() && !IsBuy()){
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            isStart = true;
            isFinal = false;
   }
}
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//+----------------------------------------------------------------------------+
double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }                                                                
//+------------------------------------------------------------------+
bool findPending(int ticket) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }

   for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }
   return false;
}
//+------------------------------------------------------------------+
void deletePending(int magic) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == magic) {
            if(OrderType() != OP_BUY && OrderType() != OP_SELL) {
               if(!OrderDelete(OrderTicket())) {
                  Print("Ошибка удаления отложеного одера: ", GetLastError());
               }
            }
            break;
         }
      }
   }
}
//+------------------------------------------------------------------+
bool IsSell()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_SELL)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
//+------------------------------------------------------------------+
bool IsBuy()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_BUY)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
 
SGarnov:

Entfernt, keine Kompilierungsfehler, nur 1 Warnung erscheint in der dritten Zeile der Funktion in der Spalte tp=0 mit dem Hören auf die externe Variable int tp=0. Ich verstehe nicht ganz, was dem Programmierer nicht gefällt. Alle Codes sind beigefügt, wenn Sie nicht schwer zu korrigieren sind, ist die Wahrheit irgendwo in der Nähe.

Es sieht folgendermaßen aus

//+------------------------------------------------------------------+
//|                                                   SGarnov.v2.mq4 |
//|                                           Copyright 2020, DrMak. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, DrMak."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//--- input parameters
input int      T_Profit = 2;     // Коэффициент Take Profit
input int      S_Loss   = 100;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  //Лоты
input int      Input4;
input int      Input5;
input int      Input6;

double sl_price,tp_price,t_profit,s_loss;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   t_profit = S_Loss*T_Profit;
   s_loss   = MathMax(S_Loss, MarketInfo(Symbol(), MODE_STOPLEVEL));
   // Проверяем наличие ордеров BUY
   if(CountOrders(_Symbol, 0)>0)
     {
      // Проверяем последний закрытый ордер SELL на наличие убытка в пунктах
      if(GetPointLastLoss(1)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(1)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
   // Проверяем наличие ордеров SELL
   if(CountOrders(_Symbol, 1)>0)
     {
      // Проверяем последний закрытый ордер BUY на наличие убытка в пунктах
      if(GetPointLastLoss(0)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(0)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
  }
//+--------------------------------------------------------------------------------------------------------------------+
//| Подсчет ордеров по типу                                                                                            |
//+--------------------------------------------------------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL                                                                 |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT                                                            |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP                                                             |
//|  6 - ордера типа Balance     -1 - Все типы ордеров                                                                 |
//+--------------------------------------------------------------------------------------------------------------------+
int CountOrders(string symb="", int or_ty=-1) 
  {
   int cnt=0;
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+----------------------------------------------------------------------------+
//| Модификация ордера                                                         |
//+----------------------------------------------------------------------------+
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//+----------------------------------------------------------------------------+
void ModifyOrder(string symb="", double sl=0, double tp=0)
  {
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(OrderStopLoss()==0)
              {
               if(OrderType()==OP_BUY)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-sl_price, OrderOpenPrice()+tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
               if(OrderType()==OP_SELL)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+sl_price, OrderOpenPrice()-tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//|  0 - последний ордер BUY                                                   |
//|  1 - последний ордер SELL                                                  |
//+----------------------------------------------------------------------------+
double GetPointLastLoss( int or_ty=-1)
  {
   datetime t=0;
   double result=0,p=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); or_ty=OrderType();
                  if(or_ty==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(or_ty==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }
//+------------------------------------------------------------------+

Sie brauchen in Ihrem Fall überhaupt keine Magie

 
MakarFX:

Das ist ungefähr richtig.

In Ihrem Fall ist Magie überhaupt nicht erforderlich.

Danke, ich werde es testen und berichten. Ich hoffe, sie funktioniert genauso wie meine, fügt aber dem neuen Take einen Stopp hinzu (wenn er ausgelöst wird).

Wofür werden die externen Parameter Input4; 5; 6 benötigt?

 
SGarnov:
Danke, ich werde es testen und Ihnen berichten. Ich hoffe, sie funktioniert genauso wie meine, fügt aber einem neuen Take einen Stopp hinzu (wenn er ausgelöst wurde).

Hier gibt es nur eine Änderung. Es gibt keine Löschung oder Stornierung von Aufträgen.

Wenn Sie beschreiben, was der EA tun soll, werde ich versuchen zu helfen.

 
SGarnov:

Wofür werden die externen Parameter Input4; 5; 6 benötigt?

Ich habe vergessen zu löschen
 
MakarFX:

Wenn Sie beschreiben, was der EA tun soll, werde ich versuchen zu helfen.

Ich erteile einen schwebenden Kaufauftrag - der EA arbeitet - der schwebende Auftrag wird ausgelöst - der EA "sieht" dies und setzt einen Stop-Loss auf diesen offenen Auftrag:

Stop Loss (externer Parameter wird in den Einstellungen festgelegt);

Take Profit(externer Parameter wird in den Einstellungen im Verhältnis von z.B. 1 zu 2 eingestellt);

schwebende Verkaufsorder auf Stop-Loss-Niveau.

Mögliche Szenarien.

Variante 1.

A) Wenn der Preis Takei erreicht, entfernt der Expert Advisor den Stop Loss und eine schwebende Verkaufsorder;

Variante 2.

B) Wenn der Stop-Loss ausgelöst wird und der EA "in die Geschichte geht", dann:

Ein Verkaufsauftrag wird eröffnet und der Expert Advisor positioniert diesen Auftrag neu:

Stop Loss (externer Parameter wird in den Einstellungen festgelegt)

Take Profit + ein ausgelöster Stop Loss aus der Historie;

einen schwebenden Kaufauftrag auf dem Niveau des Stop-Loss.

Der Preis erreicht den Take - der Expert Advisor hebt den Stop-Loss und die schwebende Kauforder auf.

Und umgekehrt, wenn die Arbeit mit einem schwebenden Verkaufsauftrag beginnt.

Und so arbeitet der Advisor, bis er seine Arbeit mit dem externen Parameter Stop Loss Nummer stoppt (in meinem Fall ist es 2, das bedeutet, dass die Variante 2 3 Mal wiederholt wird und der Advisor in Zukunft aufhört zu arbeiten und alle ausstehenden Aufträge löscht, der erste Stop wird nicht berücksichtigt).

Wenn takei nicht erreicht wird und Variante 2 wiederholt wird, dann werden 2 Stops zu takei hinzugefügt und so weiter, es hängt vom eingestellten externen Parameter"Stop Loss count" ab.


Der Code, den ich legte bis funktioniert, wie es sollte, mit Ausnahme des Problems, das ich beschrieben (sieht nicht in der Geschichte von 1 oder 2 Haltestellen, die auf die Aufnahme hinzufügen sollte).

Zum Beispiel so.

 
SGarnov:

Ich erteile einen schwebenden Kaufauftrag - der EA arbeitet - der schwebende Auftrag wird ausgelöst - der EA "sieht" dies und setzt einen Stop Loss auf diesen offenen Auftrag:

Stop Loss (externer Parameter wird in den Einstellungen festgelegt);

Take Profit(externer Parameter wird in den Einstellungen im Verhältnis von z.B. 1 zu 2 eingestellt);

schwebende Verkaufsorder auf Stop-Loss-Niveau.

Mögliche Szenarien.

Variante 1.

A) Wenn der Preis Takei erreicht, entfernt der Expert Advisor den Stop Loss und eine schwebende Verkaufsorder;

Variante 2.

B) Wenn der Stop-Loss ausgelöst wird und der EA "in die Geschichte geht", dann:

Ein Verkaufsauftrag wird eröffnet und der Expert Advisor positioniert diesen Auftrag neu:

Stop Loss (externer Parameter wird in den Einstellungen festgelegt)

Take Profit + ein ausgelöster Stop Loss aus der Historie;

einen schwebenden Kaufauftrag auf dem Niveau des Stop-Loss.

Der Preis erreicht den Take - der Expert Advisor hebt den Stop-Loss und die ausstehende Kauforder auf.

Und umgekehrt, wenn die Arbeit mit einem schwebenden Verkaufsauftrag beginnt.

Und so arbeitet der Advisor, bis er seine Arbeit mit dem externen Parameter Stop Loss Nummer stoppt (in meinem Fall ist es 2, das bedeutet, dass die Variante 2 3 Mal wiederholt wird und der Advisor in Zukunft aufhört zu arbeiten und alle ausstehenden Aufträge löscht, der erste Stop wird nicht berücksichtigt).

Wenn takei nicht erreicht wird und Variante 2 wiederholt wird, dann werden 2 Stops zu takei hinzugefügt und so weiter, es hängt vom eingestellten externen Parameter"Stop Loss count" ab.


Der Code, den ich legte bis funktioniert, wie es sollte, mit Ausnahme des Problems, das ich beschrieben (sieht nicht in der Geschichte von 1 oder 2 Haltestellen, die auf die Aufnahme hinzufügen sollte).

Das geht so.

"Anzahl der Stop-Losses" - in einer Reihe oder für den aktuellen Tag?

 
MakarFX:

"Anzahl der Stop-Losses" - in einer Reihe oder für den aktuellen Tag?

Die Anzahl der Stopps in einer Reihe für ein Währungspaar.

Um die Historie zu analysieren, kennzeichnet der Expert Advisor die Orders zunächst mit ihren IDs, findet sie aber nicht in der Historie. Ich dachte, dass OrderMagikNumber() nach ihnen suchen würde. Vielleicht wegen der Tatsache, dass in der Geschichte hält von verschiedenen Währungspaaren der EA stoppt "sehen" sie?

die Quelle noch einmal anführen? Alles, was er tun muss, ist, "die Suche nach Stop Trades aus der Historie zu korrigieren und sie zu den neu platzierten Take zu addieren".
Grund der Beschwerde: