MQL4 ve MQL5 ile ilgili herhangi bir acemi sorusu, algoritmalar ve kodlar hakkında yardım ve tartışma - sayfa 1549

 
MakarFX :

Ne yapacağını bildiğinde konuşmak iyidir...

"maksimum yararlı bilgiyi nasıl çıkaracağınız" konusunda tavsiyelerde bulunun

Zaten her şeyi yeterince açık bir şekilde söyledim. peki özelden soracağım

İşte iki işlev ve her ikisi de tarihsel sıraları yineliyor

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

Aynı siparişlerde iki döngü. Bu işlevlerin döndürdüğü her şeyi tek bir döngüde almanın bir yolu var mı?

 

merhaba!

Baykuşa yapılan işlemlerin darbesini bağlamaya çalışıyorum. Talimatlarda belirtildiği gibi yapıyorum: https://www.mql5.com/ru/forum/128200

derleme sırasında hata yok, ancak test cihazında kapak çalışmıyor.

Günlük bir hata veriyor:

2021.07.29 20:06:34.316 2015.01.08 22:10:00 AUDUSD,M5 kodunu çevirerek SMA: OrderSend hatası 130

2021.07.29 20:06:34.316 2015.01.08 22:05:45 AUDUSD,M5 kodunu çevirerek SMA: OrderSend hatası 4107

2021.07.29 20:06:34.316 2015.01.08 22:05:45 AUDUSD,M5 kodu aracılığıyla geri dönüşlü SMA: OrderSend işlevi için geçersiz stoploss

söyle lütfen, sorun ne burada?

Ben kendim, belirtilen değişkenlerin

int ReversOrderSend (dize sembolü,int cmd,çift hacim,çift fiyat,int kayma,çift stoploss,çift kar al,dize yorumu,int magic=0,datetime son kullanma=0,renk ok_color=CLR_NONE)

ana kodla ilgili değil.

farklı terminallerde denendi, 4 ve 5 işareti. hata her yerde aynı.

işte kodun tamamı:

 //+-----------------------------------------------------------------------------------------------+
//|                                                                     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 :

Zaten her şeyi yeterince açık bir şekilde söyledim. peki özelden soracağım

İşte iki işlev ve her ikisi de tarihsel sıraları yineliyor

Aynı siparişlerde iki döngü. Bu işlevlerin döndürdüğü her şeyi tek bir döngüde almanın bir yolu var mı?

Alexey, zaten yazdım, iyi bir programcı olduğunu biliyorum!

Ama ben bir programcı değilim ve sizin için "yeterince açık" olan benim için karanlık bir orman...

Ve yaklaşık iki döngü, o zaman benim için "Her şeyi tek bir döngüde elde etmek" hiçbir şekilde çünkü. farklı veri türleri döndürürler.

 
MakarFX :

Alexey, zaten yazdım, iyi bir programcı olduğunu biliyorum!

Ama ben bir programcı değilim ve sizin için "yeterince açık" olan benim için karanlık bir orman...

Ve yaklaşık iki döngü, o zaman benim için "Her şeyi tek bir döngüde elde etmek" hiçbir şekilde çünkü. farklı veri türleri döndürürler.

dönüş türlerinin bununla hiçbir ilgisi yoktur. Aynı veri için farklı kontroller ve filtreler ile 2 döngü varsa, her zaman her şeyi tek bir döngüye koyabilirsiniz, ancak kod çok net okumayacaktır, ancak daha hızlı çalışması gerekir) Hata ayıklama aşamasında, yapmıyorum her şey bir döngüde. Farklı böceklerde aramak daha kolaydır.

 
MakarFX :

Alexey, zaten yazdım, iyi bir programcı olduğunu biliyorum!

Ama ben bir programcı değilim ve sizin için "yeterince açık" olan benim için karanlık bir orman...

Ve yaklaşık iki döngü, o zaman benim için "Her şeyi tek bir döngüde elde etmek" hiçbir şekilde çünkü. farklı veri türleri döndürürler.

İki seçenek var.

  1. Küresel düzeyde yapılacak değişkenler. O zaman tüm işlevlerde mevcut olacaklar.
  2. Yerel değişkeni referansla iletin. Daha sonra bu değişken değiştirildiğinde o yerel değişken de değişecektir.
     /********************Script program start function*******************/
    void OnStart ()
     {
       int a = 0 ;
      f_0(a);
       Print (a);
     } /******************************************************************/
    
    void f_0( int & b)
     {
      b = 100 ;
     }
    64 taneye kadar böyle değişken olabilir, Allah korusun, yoksa biri beni düzeltir.
  3. Belgeleri dikkatlice ve sık sık okuyun. Bu konuda her ayrıntısıyla yazılmıştır.
 
MakarFX :

dene, sor

İlk sonuç. danışman tarafından bekleyen emirlerin verilmesiyle ilgili döviz çiftleri arasında bir çelişki var. örneğin EURUSD'ye bir gecikme attım, danışman algoritmaya göre çalıştı (1.18901 fiyattan al bir anlaşma açıldı, danışman 1.18751'de stop ve 1.19051'lik bir alım ve bir fiyattan satış için bir gecikme belirledi 1.18751 ) her şey planlandığı gibi yolunda.

Ancak fiyatların farklı olduğu ve danışmanın bekleyen bir sipariş vermek dışında her şeyi doğru yaptığı GBPUSD üzerinde bir anlaşma açmanın zamanı geldi. Bekleyen Satış 1.39393 çalıştı, EA çalışmaya başladı, 1.39633'te bir durdurma ve 1.39153'lük bir alım belirledi, ancak bekleyen alımı 1.39633'lük bir fiyata EURUSD ile tamamen kopyaladı ve bekleyen bir satışı 1.18751'lik bir fiyata koydu)

Az önce başka bir sorun keşfettim: EURUSD üzerinde açık bir işlemde, 1.18751'de bir durdurma tetiklendi ve EA'nın 1.18901'de bir durdurma ve 1.18595'lik bir alım belirlediği bekleyen satış emri açıldı. EA, tarihe geçen hedefe tetiklenmiş bir durak eklemedi.

Sorunlar bunlar.

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

merhaba!

Baykuşa yapılan işlemlerin darbesini bağlamaya çalışıyorum.

Ne demek istiyorsun? Satın aldığınız / sattığınız belirli bir fiyat aralığı mı? Ticaret danışmanı "tersine döner".

 
SGarnov :

Tünaydın. Bir danışmanla yardım edin. Stratejiye göre, bir durdurma tetiklenirse, danışman bunu bir sonraki çekime eklemelidir (puan sayısı)
kimliğe göre tarihten, ancak bir nedenden dolayı eklemiyor.

Kodda yanlış olan ne?

 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, OrderMagicNumber() öğesine doğru şekilde dikkat çekti, ancak hatayı yanlış anladı. Bu işlevin sözdizimini belgelerde okuyun... siparişler listesinde bir dizin veya belirli bir sipariş için bir bilet olmalı, ancak sihir olmamalıdır. Ve OrderTicket() burada yardımcı olmaz. Onu oraya koymaya çalışmayın.

 
SGarnov :

Ne demek istiyorsun? Satın aldığınız / sattığınız belirli bir fiyat aralığı mı? Ticaret danışmanı "tersine döner".

Kodun yazarı, anladığım kadarıyla aşağıdakileri önerdi:

eğer bir baykuş stop ve al ile bir alış işlemi açarsa, o zaman onun kod parçası aynı zamanda aynı yerde (spread'i hesaba katarak) bir alış işlemi yerine stop ve al ile bir satış işlemi açar.

bu nedenle EA'nın giriş noktası arama mantığı değişmez, sadece yayılma dikkate alınarak yön değişir.

tam ihtiyacım olan şey bu

 
MakarFX :

Bu danışmandan ne istediğinizi kısaca açıklayın (çalışma mantığı),

aksi halde bana kodunuzda fazladan bir sürü şey var gibi geliyor ya da bir şey anlamıyorum.

baykuşlar algoritmalarına göre fırsatlar açmalıdır

stop ise, bir sonraki işlem martin ile olur ve bu şekilde belirttiğim çarpma sayısına kadar devam eder (fonksiyon - OrdersClose = ..... ;).

daha fazla eğer baykuşlar. terminal ile birlikte kapatılır, sadece "otomatik ticaret" düğmesi, başka bir baykuş, daha sonra işin bir sonraki başlangıcı martingale tarafından artırılan sonuncudan değil, başlangıç partisinden başlar.

programı buna "eklemek" de güzel olurdu, ama bu düşünce şimdi aklıma geldi.

örneğin: Pazartesi günü başlangıç partisinden 10-00'da açıldı, belirli bir sonuca ulaşıldığında gün içinde kapandı, Salı sabahı 10-00'de tekrar açıldı ve başlangıç partisinden tekrar başladı.

Tümü.