OnTradeTransaction() mql4'te nasıl değiştirilir? - sayfa 8

 
Vitaly Muzichenko :

İşte bu, çözüm basit: geçmişi değiştirmek için bir kontrol daha sunuyoruz, böylece hiçbir şey kaybolmaz ve %100 çalışır

Daha düşük bir OnTrade() olarak bile kullanılabilir.

 void OnTrade()
 {
  ...
 }

static __OTotal = - 1 ;
static __HTotal = - 1 ;
int OT= OrdersTotal ();
int HT=OrdersHistoryTotal();
   if (OT!=__OTotal || HT!=__HTotal) // если изменилось - выполняем
   {
     OnTrade(); // здесь дёргаем текущую ситуацию на счёте и заполняем структуры
     __OTotal= OrdersTotal (); // запомним текущее количество
     __HTotal=OrdersHistoryTotal(); // запомним количество в истории
   }
 
Vitaly Muzichenko :

Zayıf bir zihin gibi görünüyor)

Nasıl uygulanır?

Sadece bir sorun var ve çok nadir oluyor, birkaç yıl sonra ilk kez bugün keşfettim, belki ondan önceydi, fark etmemiştim.


Sembolün adını oluşturan harflerin kodlarının değerlerini hesaplamak için hash toplamının hesaplanmasından – sembolün adı hash toplamının ulong değerine nasıl eklenebilir – bahsetmiştim.

 
Vitaly Muzichenko :

İşte bu, çözüm basit: geçmişi değiştirmek için bir kontrol daha sunuyoruz, böylece hiçbir şey kaybolmaz ve %100 çalışır

İşte #3 numaralı makalemden bir alıntı:

-------

Yapıdaki hash toplamına daha yakından bakalım.
Hesapta meydana gelen değişikliği doğru bir şekilde tespit edebilmemiz için emir ve pozisyon sayısını bilmemiz yeterli olmayacaktır - bekleyen bir emir silinebilir, bu durumda hesaptaki toplam emir ve pozisyon sayısı değişecektir. Ama... bekleyen bir emir işe yarayabilir ve bir pozisyon haline gelebilir. Bu durumda, toplam emir ve pozisyon miktarı değişmeyecektir (hedge hesapları ve MQL4 için) - pozisyon sayısı arttı, ancak sipariş sayısı azaldı ve sonuç olarak toplam sayı aynı kaldı. Bize uymuyor.

Bir bilet düşünün. Bekleyen bir emir eklemek/kaldırmak, hesaptaki toplam bilet miktarını değiştirir, bekleyen bir emri tetiklemek, hesaptaki toplam bilet miktarını değiştirmez.

Toplam hacmi düşünün. Bekleyen bir sipariş verdi veya sildi hesaptaki toplam hacim değişti, açıldı, kapandı veya pozisyon değişti - hesaptaki toplam tutar değişti. Uygun görünüyor, ancak yine de bekleyen bir siparişin etkinleştirilmesi toplam hacmi değiştirmeyecek.

Bu yüzden pozisyonun bir özelliğine daha bakıyoruz - milisaniye cinsinden değişim süresi: yeni bir pozisyon açmak toplam pozisyon değiştirme süresini değiştirecek, kısmi kapanış pozisyon değiştirme süresini değiştirecek, netleştirme hesabına hacim eklemek toplam pozisyon değiştirme süresini değiştirecek.

Tüm bunlardan hangisi, hesapta meydana gelen değişikliği açık bir şekilde belirlememiz için uygundur? Bilet + pozisyon değiştirme zamanı. Hadi kontrol edelim:

  • Pozisyon açıldı - bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Pozisyonu kapattı bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Bekleyen bir sipariş verdi bilet miktarı değişti + pozisyon değiştirme süresi miktarı değişmedi bir değişiklik var
  • Bekleyen sipariş silindi - bilet miktarı değişti + pozisyon değiştirme süresi miktarı değişmedi - bir değişiklik var
  • Bekleyen sipariş etkinleştirildi — bilet miktarı değişmedi + pozisyon değiştirme zamanının miktarı değişti bir değişiklik var
  • Bir pozisyonun kısmi kapanması — bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Bir konuma hacim ekleme — bilet miktarı değişmedi + pozisyon değiştirme zamanının miktarı değişti bir değişiklik var
Böylece hash toplamı için milisaniye cinsinden bilet + pozisyon değiştirme süresini kullanacağız.

Ancak burada, hash toplamına sembolü eklemedim - bunun için bir emsal yoktu. Ama geçmişi kontrol etmekle birlikte benim için çalışıyor. Bu nedenle - hatasız yerine getirmelidir. Ancak yine de kontrol edeceğim.

Библиотека для простого и быстрого создания программ для MetaTrader (Часть III): Коллекция рыночных ордеров и позиций, поиск и фильтрация
Библиотека для простого и быстрого создания программ для MetaTrader (Часть III): Коллекция рыночных ордеров и позиций, поиск и фильтрация
  • www.mql5.com
В первой части данного цикла статей мы начали создавать большую кроссплатформенную библиотеку, целью которой является облегчение создания программ для платформы MetaTrader 5 и MetaTrader 4. Во второй части продолжили развитие библиотеки и сделали коллекцию исторических ордеров и сделок. В данной части повествования создадим класс для удобного...
 
Vitaly Muzichenko :

İşte bu, çözüm basit: geçmişi değiştirmek için bir kontrol daha sunuyoruz, böylece hiçbir şey kaybolmaz ve %100 çalışır

Ve evet. Açık emirlerin sayısı değişmezse, geçmişteki sayı değişecektir. (Gecikmeleri umursamıyorum - onları kullanmıyorum) Ve sadece bir olayı yakalamak için büyükannenizi tüm gün boyunca hiçbir şey için emirler arasında sıralamak zorunda değilsiniz.

Ve eğer kullanıcının aklına bir SMS geldiyse ve son bir ay için olanın tamamı yerine geçmişi terminalde yansıtmaya karar verdiyse, o zaman ölümcül olmayan tüm siparişlerin aranmasıyla ekstra bir kontrol yapılacaktır. , bir kez değil.

İyi bir çözüm gibi görünüyor. Ve hiçbir şeye bağlı olmadan, sadece olanı kullanarak - ve bir ticaret hesabı ve bir terminal var.

 
Artyom Trishkin :

İşte #3 numaralı makalemden bir alıntı:

-------

Yapıdaki hash toplamına daha yakından bakalım.
Hesapta meydana gelen değişikliği doğru bir şekilde tespit edebilmemiz için emir ve pozisyon sayısını bilmemiz yeterli olmayacaktır - bekleyen bir emir silinebilir, bu durumda hesaptaki toplam emir ve pozisyon sayısı değişecektir. Ama... bekleyen bir emir işe yarayabilir ve bir pozisyon haline gelebilir. Bu durumda, toplam emir ve pozisyon miktarı değişmeyecektir (hedge hesapları ve MQL4 için) - pozisyon sayısı arttı, ancak sipariş sayısı azaldı ve sonuç olarak toplam sayı aynı kaldı. Bize uymuyor.

Bir bilet düşünün. Bekleyen bir emir eklemek/kaldırmak, hesaptaki toplam bilet miktarını değiştirir, bekleyen bir emri tetiklemek, hesaptaki toplam bilet miktarını değiştirmez.

Toplam hacmi düşünün. Bekleyen bir sipariş verdi veya sildi hesaptaki toplam hacim değişti, açıldı, kapandı veya pozisyon değişti - hesaptaki toplam tutar değişti. Uygun görünüyor, ancak yine de bekleyen bir siparişin etkinleştirilmesi toplam hacmi değiştirmeyecek.

Bu yüzden pozisyonun bir özelliğine daha bakıyoruz - milisaniye cinsinden değişim süresi: yeni bir pozisyon açmak toplam pozisyon değiştirme süresini değiştirecek, kısmi kapanış pozisyon değiştirme süresini değiştirecek, netleştirme hesabına hacim eklemek toplam pozisyon değiştirme süresini değiştirecek.

Tüm bunlardan hangisi, hesapta meydana gelen değişikliği açık bir şekilde belirlememiz için uygundur? Bilet + pozisyon değiştirme zamanı. Hadi kontrol edelim:

  • Pozisyon açıldı - bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Pozisyonu kapattı bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Bekleyen bir sipariş verdi bilet miktarı değişti + pozisyon değiştirme süresi miktarı değişmedi bir değişiklik var
  • Bekleyen sipariş silindi - bilet miktarı değişti + pozisyon değiştirme süresi miktarı değişmedi - bir değişiklik var
  • Bekleyen sipariş etkinleştirildi — bilet miktarı değişmedi + pozisyon değiştirme zamanının miktarı değişti bir değişiklik var
  • Bir pozisyonun kısmi kapanması — bilet miktarı değişti + pozisyon değiştirme zamanı miktarı değişti bir değişiklik var
  • Bir konuma hacim ekleme — bilet miktarı değişmedi + pozisyon değiştirme zamanının miktarı değişti bir değişiklik var
Böylece hash toplamı için milisaniye cinsinden bilet + pozisyon değiştirme süresini kullanacağız.

Ancak burada, hash toplamına sembolü eklemedim - bunun için bir emsal yoktu. Ama geçmişi kontrol etmekle birlikte benim için çalışıyor. Bu nedenle - hatasız yerine getirmelidir. Ancak yine de kontrol edeceğim.

Şişman karar verirken böyle bir seçeneğe gerek yok.

Teşekkür ederim!

 
Vitaly Muzichenko :

Şişman karar verirken böyle bir seçeneğe gerek yok.

Teşekkür ederim!

"Cesur" çünkü yerel bir çözüm için değil, OnTradeXXXX için tam teşekküllü bir ikamenin parçalarından biri olarak yapıldı. Kompozisyonda tarihi eser de vardır.

Ve büyük bir artı olarak - programdaki herhangi bir sipariş ve pozisyonu herhangi bir ihtiyaç için aramak ve sıralamak için hazır veriler (programın ihtiyaçları için siparişleri ve pozisyonları yeniden aramaya gerek yok - her şey zaten listelerde). Ve bir artı daha - program, MQL4'te pozisyonun hangi sırayla oluşturulduğunu biliyor ve bu, yukarıda belirtilen seçeneklerde yapılamaz.

Ama tekrar ediyorum - kütüphane, her şeyi çok uzun ve pahalı bir süre için yapanlar için hayatı kolaylaştırmak için yapılıyor. Elbette hiçbir şey için ısrar etmiyorum :)

 
Aleksandr Volotko :

Ve evet. Açık emirlerin sayısı değişmezse, geçmişteki sayı değişecektir. ( Gecikmeleri umursamıyorum - onları kullanmıyorum ) Ve sadece bir olayı yakalamak için büyükannenizi tüm gün boyunca hiçbir şey için emirler arasında sıralamak zorunda değilsiniz.

Ve eğer kullanıcının aklına bir SMS geldiyse ve son bir ay için olanın tamamı yerine geçmişi terminalde yansıtmaya karar verdiyse, o zaman ölümcül olmayan tüm siparişlerin aranmasıyla ekstra bir kontrol yapılacaktır. , bir kez değil.

İyi bir çözüm gibi görünüyor. Ve hiçbir şeye bağlı olmadan, sadece olanı kullanarak - ve bir ticaret hesabı ve bir terminal var.

Bütün günü geçirmemek için sadece pozisyon değiştirmeye, açmaya, kapamaya, yani bir pozisyonun değişmesine neden olabilecek koşullar sağlandığında kontrolü yapabilirsiniz. uzmanın açmak için kullandığı fiyatlara ulaşmaya odaklanın, TP, SL. Eh, evet, uzmanın mantığına göre değişir, orada neyin daha ucuz olduğunu siz daha iyi bilirsiniz.

 
Aleksey Mavrin :

Bütün günü geçirmemek için sadece pozisyon değiştirmeye, açmaya, kapatmaya, yani bir pozisyonun değişmesine neden olabilecek koşullar sağlandığında kontrolü yapabilirsiniz. uzmanın açmak için kullandığı fiyatlara ulaşmaya odaklanın, TP, SL. Eh, evet, uzmanın mantığına göre değişir, orada neyin daha ucuz olduğunu siz daha iyi bilirsiniz.

Bir danışman (bir bilgisayarda, bir kıtada) işlem yapar. Bir diğeri (başka bir bilgisayarda, başka bir kıtada) kendi işini yapıyor. Çözüm zaten bulundu.

 
fxsaber :

Tekrarlanabilir bir örnek verebilirseniz minnettar olurum (ticaret geçmişi yoklaması olmadan).

İşte olanlar (burada konu dışı olsa da, burada sorulmuştur).

Canlı kesilmiş. MT4 uyumluluğu yok (elbette), hata işleme yok vb.

Alım satım ilkeldir, AL'ı açar, SL/TP ile kapatır. Tek nokta OnTradeTransaction() 'a karşı "sunucu yoklaması"nı göstermektir.

Belirtilen aralık için 2.34s vs 3.06s aldı. Sunucu işlevlerindeki düşük yük nedeniyle fark küçüktür (yalnızca bir konum, sihir ve sembol kontrolü yoktur). Gerçek bir Expert Advisor'da fark çok daha büyük olacaktır. Fark, sinyallerin hesaplanması ve takiplerin eklenmesi nedeniyle hafifçe dengelenecektir, ancak bunların her tikte yapılması gerekmez. M1'de hesaplanan ATR'm var, ancak 6 saat için (yani, TF yükseltme için yer var). Ve sondaki ve başa baş, H3'te hesaplanır. Her şey stratejiye bağlı.

 // Test OnTradeTransaction.mqh
#property version    "1.00"
#property copyright "(c)2020 Edgar Akhmadeev"
#property link        "https://www.mql5.com/en/users/dali"
// 2020.01.27

//      Primitive expert to test OnTradeTransaction().
//      BUY only one position a time. There's no any signals.
//      Try OHLC M1 EURUSD 2016.12.19-2018.04.14 (bull trend) with default SL/TP.



//#define TESTER



#define MT4_TICKET_TYPE
#include <MT4Orders.mqh>
#include <mql4_to_mql5.mqh>



struct PosInfoBase {
         double                   price, sl, tp;
         datetime                 time;
         int                      ticket;
         ENUM_ORDER_TYPE 	type;

         #ifndef TESTER
                 int              mn;
                 string           sym;
         #endif 
};

struct PosInfo {
        PosInfoBase             base;
         int                      ticket;
};



input int        SL              = 6 ;
input int        TP              = 900 ;



MqlTick          tick;
PosInfo         posInfo         = { 0 };



#ifdef TESTER

//*************************************************************************************************************
void 
OnTradeTransaction ( const MqlTradeTransaction & trans, const MqlTradeRequest & request, const MqlTradeResult & result) {
         if (trans.type == TRADE_TRANSACTION_ORDER_DELETE && trans.order_state == ORDER_STATE_PLACED ) {
                 // No money
                 //errFatal = true;
                 return ;
        }
        
         static long lastTick;

         if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.order_state == ORDER_STATE_STARTED ) {
                 // Open on market step1, SL/Order triggered step1, SL/Order triggered step4
                
                 if (! HistoryDealSelect (trans.deal)) {
                         //errFatal = true;
                         return ;
                }
                
                 ENUM_DEAL_ENTRY entry = ( ENUM_DEAL_ENTRY ) HistoryDealGetInteger (trans.deal, DEAL_ENTRY );
                 if (entry != DEAL_ENTRY_OUT )
                         return ;
                
                 ENUM_DEAL_REASON reason = ( ENUM_DEAL_REASON ) HistoryDealGetInteger (trans.deal, DEAL_REASON );
                 if (reason != DEAL_REASON_SL && reason != DEAL_REASON_TP )
                         return ;
                
                 if (lastTick == tick.time_msc)
                         return ;

                posInfo.base.ticket = 0 ;
                InitPos();

                lastTick = tick.time_msc;
                 return ;
        }
}



#else // TESTER



//*************************************************************************************************************
bool
Support() {
        posInfo.base.ticket = 0 ;
        
         int cnt = PosTotal();
         if (cnt > 1 )
                 return false ;
        
        PosInfo _posInfo;
        
         if (cnt == 0 )
                _posInfo.base.ticket = 0 ;
         else {
                PosInfoFill(_posInfo);
                _posInfo.ticket = _posInfo.base.ticket;
        }

         //-------------------------------------------------------------------------------------------------------------
         // Position: process
        
         if (_posInfo.base.ticket != 0 && posInfo.ticket != 0 && _posInfo.base.ticket == posInfo.ticket) {
                 // Ничего не произошло, та же позиция
                
                posInfo.base.ticket = _posInfo.base.ticket;
                posInfo.base.time = _posInfo.base.time;
                 //posInfo.base.price = _posInfo.base.price;
                posInfo.base.sl = _posInfo.base.sl;
                posInfo.base.tp = _posInfo.base.tp;
        }

         //-------------------------------------------------------------------------------------------------------------
         // Инициализация новой позиции
        
         if (posInfo.base.ticket > 0 )
                 return true ;
        
         return InitPos();
}

#endif // TESTER



//*************************************************************************************************************
bool
InitPos() {
         if (! SymbolInfoTick ( _Symbol , tick))
                 return false ;
        
        posInfo.base.type = ORDER_TYPE_BUY ;
        posInfo.base.sl = NormalizeDouble (tick.bid - SL * Point , Digits ); 
        posInfo.base.tp = NormalizeDouble (tick.bid + TP * Point , Digits );       

         ResetLastError ();
         int order = OrderSend ( _Symbol , posInfo.base.type, 0.01 , tick.ask, 99 , posInfo.base.sl, posInfo.base.tp); 
         if (order < 0 )
                 return false ;
        
         if (! OrderSelect (order, SELECT_BY_TICKET))
                 return false ;

        posInfo.base.price = OrderOpenPrice();
        posInfo.ticket = posInfo.base.ticket = order;
        posInfo.base.time = tick.time;
         return true ;
}



//*************************************************************************************************************
int
PosTotal() {
         int posTotal = OrdersTotal ();
         int cnt = 0 ;
         for ( int i = posTotal - 1 ; i >= 0 ; --i) {
                 if (! OrderSelect (i, SELECT_BY_POS)) {
                         //errFatal = true;
                         return - 1 ;
                }

                 if (OrderType() > OP_SELL)
                         continue ;

                 /*
                #ifndef TESTER
                        if (OrderMagicNumber() != MagicNum)
                                continue;
                        if (OrderSymbol() != symInfo.sym)
                                continue;
                #endif 
                */
                        
                ++cnt;
        } // for
        
         return cnt;
}


        
//*************************************************************************************************************
void
PosInfoFill(PosInfo& _posInfo) {
         ZeroMemory (_posInfo);

        _posInfo.base.ticket = ( int ) PositionGetInteger ( POSITION_TICKET );
        _posInfo.base.type = ( ENUM_ORDER_TYPE ) PositionGetInteger ( POSITION_TYPE );
        _posInfo.base.price = PositionGetDouble ( POSITION_PRICE_OPEN );
        _posInfo.base.time = ( datetime ) PositionGetInteger ( POSITION_TIME );
        _posInfo.base.sl = PositionGetDouble ( POSITION_SL );
        _posInfo.base.tp = PositionGetDouble ( POSITION_TP );

         #ifndef TESTER
                _posInfo.base.mn = ( int ) PositionGetInteger ( POSITION_MAGIC );
                _posInfo.base.sym = PositionGetString ( POSITION_SYMBOL );
         #endif 
}



//*************************************************************************************************************
void 
OnTick () {
         ResetLastError ();
         if (! SymbolInfoTick ( _Symbol , tick)) {
                 int LE = GetLastError ();
                 //errFatal = true;
                 return ;
        }
        
         #ifdef TESTER

                 if (posInfo.base.ticket > 0 )
                         return ;
                
                 if (!InitPos()) {
                         //errFatal = true;
                         return ;
                }

         #else   // TESTER
                
                 if (!Support()) {
                         //errFatal = true;
                         return ;
                }
        
         #endif // TESTER
}



//*************************************************************************************************************
int 
OnInit () {
         return INIT_SUCCEEDED ;
}



//*************************************************************************************************************
void 
OnDeinit ( const int reason) {
}
 
prostotrader :

Umutsuzca çağın gerisindesiniz!

Bu etkinlikler uzun süre garantilidir !

OnTradeTransaction() içinde bazı eylemlerin gerçekleştirilmesi gereken bir olay olduğunu, ancak bu eylemleri gerçekleştirmeye yönelik ilk denemede bir hata oluştuğunu varsayalım. Ne yapalım? Açıkçası, tekrar denemeniz gerekiyor ve bunun için bu eylemleri tekrarlama ihtiyacıyla ilgili verileri bir yere kaydetmeniz gerekiyor - büyük olasılıkla, bu verilerin kaydedilmesi danışmanın olağan global değişkenlerinde veya statik işlevlerde yapılır. Ve aniden terminali yeniden başlatmak zorunda kaldım... veriler gitmişti.

Ve mevcut durumu ve tarihi analiz ettiğinizde hiçbir şey uçup gitmez.