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

 
MakarFX:

Es ist gut zu reden, wenn man weiß, was zu tun ist...

mir mit Ratschlägen zu helfen, wie man "so viele nützliche Informationen wie möglich herausbekommt".

Ich habe alles ganz klar gesagt. Lassen Sie mich eine Frage an Sie persönlich richten.

Hier sind zwei Funktionen, die beide durch historische Aufträge gehen

//+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+

Zwei Zyklen für dieselben Aufträge. Sie können nicht alles, was diese Funktionen zurückgeben, in einem Zyklus erhalten, richtig?

 

Guten Tag!

Ich versuche, der Eule eine Handelsumkehr hinzuzufügen. Ich mache es wie in der Anleitung beschrieben: https://www.mql5.com/ru/forum/128200

Ich habe keine Fehler beim Kompilieren, aber mein Tester funktioniert nicht mit flip.

Das Protokoll gibt einen Fehler aus:

2021.07.29 20:06:34.316 2015.01.08 22:10:00 SMA mit Flip Through Code AUDUSD,M5: OrderSend Fehler 130

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA mit Umkehrung über AUDUSD,M5: OrderSend Fehler 4107

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA mit Flip über AUDUSD,M5: ungültiger Stoploss für OrderSend-Funktion

Können Sie mir bitte sagen, was hier das Problem ist?

Ich selbst bin der Meinung, dass die Variablen, die in

int ReversOrderSend (string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment,int magic=0,datetime expiration=0,color arrow_color=CLR_NONE)

Sie stehen in keinem Zusammenhang mit dem Hauptcode.

Ich habe es mit verschiedenen Terminals, 4 und 5 Zeichen ausprobiert.

Hier ist der gesamte Code:

//+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                 Copyright 2016, Andrey Minaev |
//|                                                     https://www.mql5.com/ru/users/id.scorpion |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2016, Andrey Minaev"
#property link      "https://www.mql5.com/ru/users/id.scorpion"
#property version   "1.00"
#property strict

// Параметры советника
extern string sParametersEA = "";     // Параметры советника
extern double dLots         = 0.01;   // Количество лотов
extern int    iStopLoss     = 30;     // Уровень убытка (в пунктах)
extern int    iTakeProfit   = 30;     // Уровень прибыли (в пунктах)
extern int    iSlippage     = 3;      // Проскальзование (в пунктах)
extern int    iMagic        = 1;      // Индентификатор советника
extern double K_Martin     = 2.0;
extern int    OrdersClose  = 5;
extern int    DigitsLot    = 2;
extern int    ReversOrder  = 0;             // Переворот сделок 1-да; 0-нет;
// Параметры индикатора
extern string sParametersMA = "";     // Параметры индикатора
extern int    iPeriodMA     = 14;     // Период усреднения
// Глобальные переменные
double dMA;
//+-----------------------------------------------------------------------------------------------+
int OnInit()
  {
// Если брокер использует 3 или 5 знаков после запятой, то умножаем на 10
   if(Digits == 3 || Digits == 5)
     {
      iStopLoss   *= 10;
      iTakeProfit *= 10;
      iSlippage   *= 10;
     }

   return(INIT_SUCCEEDED);
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick()
  {
// Получим значение индикатора
   dMA = iMA(Symbol(), 0, iPeriodMA, 0, MODE_SMA, PRICE_CLOSE, 0);

// Если нет открытых ордеров, то входим в условие
   if(bCheckOrders() == true)
     {
      // Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

      // Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
bool bCheckOrders()
  {
// Переберем в цикле ордера, для проверки открытых ордеров данным советником
   for(int i = 0; i <= OrdersTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
            return(false);

   return(true);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if(dMA > Open[1] && dMA < Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   if(dMA < Open[1] && dMA > Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_BUY, LOT(), Ask, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_SELL, LOT(), Bid, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify(int iOTi)
  {
   int    iOTy = -1;   // Тип ордера
   double dOOP = 0;    // Цена открытия ордера
   double dOSL = 0;    // Стоп Лосс
   int    iMag = 0;    // Идентификатор советника

   double dSL = 0;     // Уровень убытка
   double dTP = 0;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if(OrderSelect(iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMag)
     {
      // Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
      if(dOSL == 0)
        {
         if(iOTy == OP_BUY)
           {
            dSL = NormalizeDouble(dOOP - iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP + iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }

         if(iOTy == OP_SELL)
           {
            dSL = NormalizeDouble(dOOP + iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP - iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError(int iErr)
  {
   switch(iErr)
     {
      case 129:   // Неправильная цена
      case 135:   // Цена изменилась
      case 136:   // Нет цен
      case 138:   // Новые цены
         Sleep(1000);
         RefreshRates();
         break;

      case 137:   // Брокер занят
      case 146:   // Подсистема торговли занята
         Sleep(3000);
         RefreshRates();
         break;
     }
  }
//+-----------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LOT()
  {
   int n=0;
   double OL=dLots;
   for(int j = OrdersHistoryTotal()-1; j >= 0; j--)
     {
      if(OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
           {
            if(OrderProfit()<0)
              {
               if(n==0)
                  OL=NormalizeDouble(OrderLots()*K_Martin,DigitsLot);
               n++;
               if(n>=OrdersClose)
                 {
                  Comment("1");
                  return(dLots);
                 }
              }
            else
              {
               if(n==0)
                 {
                  Comment("2");
                  return(dLots);
                 }
               else
                 {
                  Comment("3");
                  return(OL);
                 }
              }
           }
        }
     }
   return(OL);
  }
//------------------------------------------------------------------
int ReversOrderSend (string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment,int magic=0,datetime expiration=0,color arrow_color=CLR_NONE)
{
int Ret=0;
double sprd=MarketInfo(symbol,MODE_SPREAD)*Point;
//Print ("----------------------------",sprd);
if (ReversOrder==0) // Открываем ордера без разворота
{
Ret=OrderSend (symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color);
}
if (ReversOrder==1)
{
///////////////
if (cmd==OP_SELLSTOP) // Переворачиваем ордера OP_SELLSTOP
{
Ret=OrderSend (symbol,OP_BUYLIMIT,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYSTOP) // Переворачиваем ордера OP_BUYSTOP
{
Ret=OrderSend (symbol,OP_SELLLIMIT,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
///////////////
if (cmd==OP_SELL) // Переворачиваем ордера OP_SELL
{
Ret=OrderSend (symbol,OP_BUY,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUY) // Переворачиваем ордера OP_BUY
{
Ret=OrderSend (symbol,OP_SELL,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
//////////////
if (cmd==OP_SELLLIMIT) // Переворачиваем ордера OP_SELLLIMIT
{
Ret=OrderSend (symbol,OP_BUYSTOP,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYLIMIT) // Переворачиваем ордера OP_BUYLIMIT
{
Ret=OrderSend (symbol,OP_SELLSTOP,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
}
return (Ret);
}
Предлагаю функцию реверса ордеров, для сливающих советников.
Предлагаю функцию реверса ордеров, для сливающих советников.
  • 2010.08.24
  • www.mql5.com
Помню, поначалу сталкивался с вопросом, как грамотно "перевернуть" ордера с покупки на продажу и наоборот...
 
Alexey Viktorov:

Ich habe es schon deutlich genug gesagt. Ich werde Ihnen eine persönliche Frage stellen.

Hier sind zwei Funktionen, die beide historische Aufträge durchlaufen

Es gibt zwei Schleifen für dieselben Aufträge. Sie können nicht alles, was diese Funktionen zurückgeben, in einem Zyklus erhalten, richtig?

Alexej, ich habe bereits geschrieben, dass du ein guter Programmierer bist!

Aber ich bin kein Programmierer, und was für Sie "klar genug" ist, ist für mich nicht so klar...

Was die beiden Schleifen betrifft, so ist für mich"In einer Schleife alles holen" nicht möglich, da sie unterschiedliche Datentypen zurückgeben.

 
MakarFX:

Alexey, ich habe schon geschrieben, ich weiß, dass du ein guter Programmierer bist!

Aber ich bin kein Programmierer und was für Sie "klar genug" ist, ist für mich ein dunkler Wald...

Was die beiden Schleifen betrifft, so ist es für mich nicht möglich,"alles in einer Schleife zu erhalten" , da sie unterschiedliche Datentypen zurückgeben.

Die zurückgegebenen Typen haben damit nichts zu tun. Wenn es 2 Schleifen über dieselben Daten mit unterschiedlichen Prüfungen und Filtern gibt, kann man immer alles in eine Schleife packen, aber der Code liest sich dann nicht so klar, aber es sollte schneller gehen. Es ist einfacher, Fehler in anderen Programmen zu finden.

 
MakarFX:

Alexey, ich habe schon geschrieben, ich weiß, dass du ein guter Programmierer bist!

Aber ich bin kein Programmierer und was für Sie "klar genug" ist, ist für mich ein dunkler Wald...

Was die beiden Schleifen betrifft, so ist es für mich nicht möglich,"in einer Schleife alles zu erhalten" , da sie unterschiedliche Datentypen zurückgeben.

Ich habe zwei Varianten.

  1. Erstellen Sie Variablen auf globaler Ebene. Dann werden sie in allen Funktionen verfügbar sein.
  2. Übergeben Sie die lokale Variable per Referenz. Wenn Sie dann diese Variable ändern, wird die lokale Variable geändert.
    /********************Script program start function*******************/
    void OnStart()
     {
      int a = 0;
      f_0(a);
      Print(a);
     }/******************************************************************/
    
    void f_0(int & b)
     {
      b = 100;
     }
    Und es kann bis zu 64 solcher Variablen geben, Gott bewahre, dass ich lüge. Wenn ich falsch liege, kann mich jemand korrigieren.
  3. Lesen Sie die Dokumentation aufmerksamer. Sie ist dort sehr detailliert beschrieben.
 
MakarFX:

Ich habe einen Konflikt zwischen anhängigen Aufträgen.

Erstes Ergebnis: Es gibt einen Konflikt zwischen Währungspaaren und EA hat einen Konflikt bei der Platzierung von Pending Orders. Zum Beispiel habe ich eine Pending Order für EURUSD platziert, EA hat den Algorithmus befolgt (Kauf bei 1.18901, offene Position, EA hat Stop bei 1.18751 gesetzt, Take Profit bei 1.19051 und Verkaufsorder bei 1.18751), alles ist in Ordnung wie geplant.

Aber jetzt ist es an der Zeit, ein Geschäft mit GBPUSD zu eröffnen, wo die Preise anders sind und der EA alles richtig macht, außer eine Pending Order zu setzen. Eine Verkaufsorder bei 1,39393 wurde ausgelöst, und der EA versuchte, sie zu öffnen, einen Stopp bei 1,39633 zu setzen und 1,39153 zu nehmen, aber die Kauforder bei 1,39633 wurde vom EURUSD dupliziert und die Verkaufsorder wurde bei 1,18751 gesetzt)

Ich habe soeben ein weiteres Problem entdeckt: ein Stop bei 1,18751 und ein schwebender Verkaufsauftrag bei 1,18901 und Take 1,18595 wurden für EURUSD eröffnet. Der Expert Advisor hat den ausgelösten Stop, der in der Historie steht, nicht hinzugefügt.

Das sind die Probleme.

 
законопослушный гражданин:

Guten Tag!

Ich versuche, die Eule mit einer Umdrehung des Gewerbes zu versehen.

Wie meinen Sie das? Eine bestimmte Preisspanne, ab der Sie kaufen/verkaufen?

 
SGarnov:

Guten Tag. Hilfe mit dem EA. Nach der Strategie, wenn ein Stop ausgelöst, dann sollte der EA hinzufügen (die Anzahl der Punkte), um die nächste Reihe takeaway
aus der Geschichte von ID, aber es tut es nicht aus irgendeinem Grund.

Was ist an dem Code falsch?

if(isLimitOn && OrderSelect(OrderMagicNumber(), SELECT_BY_TICKET, MODE_HISTORY)){
            tpc += stop_loss;
            if(OrderSelect(lastMagic, SELECT_BY_TICKET)){
               if(OrderType() == OP_BUY) {
                  double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }else if(OrderType() == OP_SELL){
                  double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }
            }
               
            isLimitOn = false;
         }

Makar hat korrekt auf OrderMagicNumber() verwiesen, aber den Fehler missverstanden. Lesen Sie die Dokumentation für die Syntax dieser Funktion... es sollte entweder der Index in der Liste der Bestellungen oder das Ticket einer bestimmten Bestellung sein, aber nicht eine Magie. Und OrderTicket() wird hier nicht helfen. Versuchen Sie nicht, sie dort zu platzieren.

 
SGarnov:

Wie meinen Sie das? Eine bestimmte Preisspanne, ab der Sie kaufen/verkaufen?

Soweit ich weiß, hat der Autor des Codes Folgendes vorgeschlagen:

Wenn Eule ein Kaufgeschäft mit Stopp und Take eröffnet, dann eröffnet sein Code zur gleichen Zeit an der gleichen Stelle (unter Berücksichtigung des Spreads) ein Verkaufsgeschäft ebenfalls mit Stopp und Take anstelle eines Kaufgeschäfts.

Somit ändert sich die Logik der Suche nach einem Einstiegspunkt des EA nicht, und nur die Richtung mit berücksichtigtem Spread ändert sich.

das ist genau das, was ich brauche

 
MakarFX:

Beschreiben Sie kurz und bündig, was Sie von diesem EA erwarten (die Logik der Funktionsweise),

Ich glaube, Sie haben eine Menge unnötiger Dinge in Ihrem Code oder ich verstehe etwas nicht.

Eulen sollten Geschäfte nach ihrem eigenen Algorithmus eröffnen

wenn der Stopp, der nächste Handel mit einem Martin, und so weiter, bis die Anzahl der Multiplikationen, die ich angegeben (Funktion -OrdersClose = .....;).

Wenn die Eule zusammen mit dem Terminal deaktiviert ist, drücken Sie einfach die Taste "Auto-Trading" mit einer anderen Eule, dann wird der nächste Handel mit dem Startlot beginnen, nicht mit dem letzten, der durch ein Martingal erhöht wurde.

Es wäre auch schön, einen Zeitplan damit zu verbinden, aber diese Idee ist mir erst jetzt gekommen.

Zum Beispiel: Am Montag wurde es um 10-00 Uhr mit dem Startlos aktiviert, dann wurde es im Laufe des Tages abgeschaltet, als ein bestimmtes Ergebnis erzielt wurde, und am Dienstagmorgen wurde es um 10-00 Uhr aktiviert und wieder mit dem Startlos gestartet.

Alles.