Daha az kod, daha fazla kullanım Uzman Danışman yazmak

 

Uzman Danışmanlar için bir temel oluşturmaya çalışacağım (ya da ilgilenenler varsa deneyeceğiz). Basit şeyler için en uygun olanıdır ve uygulamalı programcıdan önemli bilgi gerektirmez.

Yerel olarak kabul edilen uygulamanın aksine, tasarım yukarıdan aşağıya olacaktır. Kullanıcının istenen kullanım durumundan ve terminalin mühendislik temellerinden değil. Yani, önce son kullanıcı için ana (ve tek) danışman dosyasını yazıyoruz, açıkça gereksiz olan her şeyi oradan kaldırıyoruz ve BT'nin çalışması için bir kütüphane yazıyoruz. Ardından yeni bir kullanım durumu ekliyoruz ve kitaplığı yükseltiyoruz.

https://www.mql5.com/ru/articles/5654 ve Sayın Karputov'un danışmanları ile karşı tez ve polemik olarak

Elbette, ilerlemeden önce "parti çizgisi"ni ve "hedef-komünizmi"ni kurmak gerekir:

- Kullanıcının stratejiyi uygulaması için 100 satır yeterlidir. (yorumların, girdilerin ve diğer #özelliklerin yanı sıra).

- aynı zamanda, kendisine yeni gelen "varlıkların" (fonksiyonlar/sınıflar/yöntemler/sabitler) sayısı en aza indirilmelidir.

- kitaplık sayılabilir sayıda dosya içermelidir.

- GUI için potansiyel olarak uygun

- eklentilerle genişletilebilir

Hedefler ulaşılabilir mi? zor, ama temelde EVET. Bazı yönlerden gelişmeler ve fikirler var. Ancak henüz hazır bir çözüm yok :-)

Mevcut adım, verilerin bir uzman tarafından alınmasını organize etmektir. Böylece kullanıcının bunları tanımlaması kolaydır, ancak aynı zamanda meta veriler ve diğer uzantılar için "kancalar" korunur. (ileriye bakmak - diğer koda göre, en azından hata ayıklama olan GUI bölümünü zaten uygulayın)


Bir başlatıcı olarak, en basit kullanım örneğini çizdim - iki MA'nın kesiştiği noktada ticaret yapıyoruz

sırasıyla, giriş kısmı şöyle görünür:

 /** ------- ПАРАМЕТРЫ СОВЕТНИКА ------
**/
input ENUM_APPLIED_PRICE FAST_MA_PRICE= PRICE_CLOSE ;
input ENUM_MA_METHOD FAST_MA_METHOD= MODE_EMA ;
input int FAST_MA_PERIOD= 14 ;
input int FAST_MA_SHIFT= 0 ;

input ENUM_APPLIED_PRICE SLOW_MA_PRICE= PRICE_CLOSE ;
input ENUM_MA_METHOD SLOW_MA_METHOD= MODE_SMA ;
input int SLOW_MA_PERIOD= 54 ;
input int SLOW_MA_SHIFT= 0 ;

Planlandığı gibi, kullanıcının yapması gereken bir sonraki şey, girdiden hangi verileri aldığını açıklamaktır. Yine de listelemek için:

 // просто перечисляем идентификаторы данных
// всех которые нужны для принятия решений
enum ENUM_SERIES {
   FAST_MA,       // id. значений FAST_MA
   SLOW_MA,       // id. значений SLOW_MA
   TOTAL_SERIES   // последний элемент перечисления = кол-во элементов
};

ve bu verileri nasıl hesapladığını / aldığını açıklayın (uzun olduğu ortaya çıktı, ancak hemen her iki terminale de)

 /// вычисление данных
/// эксперт будет обращаться к функции каждый раз когда ему необходимы данные
/// управление кешированием и очерёдность(взаимозависимость) вычислений лежит на верхнем уровне
/// @arg ea - эксперт
/// @arg id - ид.серии данных
/// @arg shift - сдвиг в серии
/// @arg data[] - кешированные результаты
/// @return double - конкретное значение для [id][shift] или EMPTY_VALUE если не может быть вычилено
/// если данные могут быть кешированы, они должны быть сохраненны в массиве data
double GetData(EA *ea, int id, int shift, double &data[])
{
#ifdef __MQL4__
   // для 4-ки всё просто - по идентификаторам серии и бара получить данные
   switch ((ENUM_SERIES)id) {
       case FAST_MA:
         return data[shift]= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
       case SLOW_MA:
         return data[shift]= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);
   }
   return EMPTY_VALUE ;
#else
   // для 5-ки несколко сложнее (и кстати не проверено) - надо ещё заводить хендлы стандартных индикаторов
   // и проводить (возможно)лишнее копирование
   static d_fast_ma= 0 ;
   static d_slow_ma= 0 ;
   if (d_fast_ma== 0 ) d_fast_ma= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
   if (d_slow_ma== 0 ) d_slow_ma= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  
   double tmp[ 1 ];
   switch ((ENUM_SERIES)id) {
       case FAST_MA: CopyBuffer (d_fast_ma, 0 ,shift, 1 ,tmp); return data[shift]=tmp[ 0 ];
       case SLOW_MA: CopyBuffer (d_slow_ma, 0 ,shift, 1 ,tmp); return data[shift]=tmp[ 0 ];
   }
   return EMPTY_VALUE ;
#endif
}

ve son olarak ticaret sinyalini tanımlayın:

 /// генерация(вычисление) сигнала при открытии бара
/// @arg ea - эксперт
/// @arg shift - номер бара в таймсерии. Типично будет 0
/// @return int - сигнал OP_BUY или OP_SELL или -1 если сигнала нет 
int SignalOfCross(EA *ea, int shift)
{
   if (FAST_MA_PRICE!= PRICE_OPEN || SLOW_MA_PRICE!= PRICE_OPEN ) shift++;
   if (ea.CrossedUp(FAST_MA,SLOW_MA,shift)) {
       return OP_BUY ;
   }
   if (ea.CrossedDn(FAST_MA,SLOW_MA,shift)) {
       return OP_SELL ;
   }
   return - 1 ;
}

PRENSİPTE HER ŞEY. Bu, bir Uzman Danışman uygulamak için yeterlidir ve açıkçası kullanıcının tonlarca belge okumasını gerektirmez. Temel düzeyde MQL yeterliliğine ihtiyacı var. Ve diğer her şey kütüphane tarafından yapılmalıdır (veya moda olan kelime motordur). Kullanıcı için oluşturulmalı, başka bir çok ciltli API öğrenmesi için değil

Bu arada, işte OnInit:

 int OnInit ()
{
   ea = new EA();
   // настраиваем таймфрейм "по умолчанию"
   //   символ и период - текущие
   //   TOTAL_SERIES наборов данных и кешируем по 30 в каждом
   //   для получения данных служит GetData
   ea.SetupTimeframe( _Symbol , _Period ,TOTAL_SERIES, 30 ,GetData);
   // настраиваем сигнал "по умолчанию"
   ea.SetupSignal(SignalOfCross);
   // ------ настройки завершены ------
   // остальная часть одинакова для всех советников
   int ret;
   if ((ret=ea. OnInit())!=INIT_SUCCEEDED ) {
       return ret;
   }
   EventSetTimer ( 60 );

   return ( INIT_SUCCEEDED );
}
  

..

Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
  • www.mql5.com
Разбирая огромное количество торговых стратегий, множество заказов на изготовление программ для терминалов MT5 и MT4, просматривая огромное разнообразие различных сайтов по тематике скриптов, индикаторов и роботов для MetaTrader, я пришёл к выводу, что всё это многообразие в подавляющем своём большинстве строится на фактически одних и тех же...
 
Lütfen tüm kodlarınızı doğru girin: peki, bu gri umutsuzluğa bakmak imkansız. Net bir eylem planı var: editördeki butona tıkladılar, kodu ortaya çıkan alana yapıştırdılar . İnatla bir metin tuvali eklersiniz ve ardından bu tuvale “kod” stilini uygulamaya çalışırsınız.
 
Vladimir Karputov :
Lütfen tüm kodlarınızı doğru girin: peki, bu gri umutsuzluğa bakmak imkansız. Net bir eylem planı var: editördeki butona tıkladılar, kodu ortaya çıkan alana yapıştırdılar . İnatla bir metin tuvali eklersiniz ve ardından bu tuvale “kod” stilini uygulamaya çalışırsınız.

o (kod) çarpık bir şekilde oraya yerleştirilmiştir. bir parça hala bir şekilde savaşılabilir ve biraz daha fazlası zaten un ..

yani, "gri umutsuzluk" hakkında, bu benim için değil - bu web yöneticileri için. 2019'da bol miktarda fonla bunu nasıl başardıkları bir sır :-)

ama ilerde daha eğlenceli hale getirmek için önce wiki üzerine az çok büyük yazılar yazıp kopyala-yapıştır ile buraya aktarıp yayınlanan kod miktarını azaltacağım.

 
Maxim Kuznetsov :

o (kod) çarpık bir şekilde oraya yerleştirilmiştir. bir parça hala bir şekilde savaşılabilir ve biraz daha fazlası zaten un ..

yani, "gri umutsuzluk" hakkında, bu benim için değil - bu web yöneticileri için. 2019'da bol miktarda fonla bunu nasıl başardıkları bir gizem :-)

ama ilerde daha eğlenceli hale getirmek için önce wiki üzerine az çok büyük yazılar yazıp kopyala-yapıştır ile buraya aktarıp yayınlanan kod miktarını azaltacağım.

Görünüşe göre şimdi kodu içeren bloğu kopyalamanız ve Not Defteri'ne yapıştırmanız gerekiyor.

Ardından not defterinden kopyalayın ve geri yapıştırın, ancak bundan önce "yeni" kod için yeni bir blok oluşturun

 

Danışman için temel şablonu oluşturdum ve ayrıca bir strateji dosyası oluşturdum.

Kullanıcı için kolay olduğunu düşünüyor musunuz?

minimum programlama bilgisi hala gereklidir!

Ve hiçbir "yardım" talimatı, video, hiçbir şey kaydetmez.

Kullanıcı daha sonra sizden onu ücretsiz stratejiler için pedal çevirmenize ihtiyaç duyacaktır.

Ve sertifikayı okumazlar.

 
Vitaly Muzichenko :

Görünüşe göre şimdi kodu içeren bloğu kopyalayıp Not Defteri'ne yapıştırmanız gerekiyor.

Ardından not defterinden kopyalayın ve geri yapıştırın, ancak bundan önce "yeni" kod için yeni bir blok oluşturun

biraz eziyet, ama "çiçek açmış" gibi görünüyor :-)

bahsedilen web yöneticileri için bahçede bir çakıl taşı (daha doğrusu bir parke taşı): yerleşik düzenleyiciye kopyala-yapıştır yaparken veya daha doğrusu, açıkça ilk "renklendirmede", editör keyfi olarak kodun bir bölümünü ısırır. o hoşlanmaz. Özellikle, "if ( (ret=ea.OnInit())!=INIT_SECEEDED) {..}" öğesini keyfi olarak düzenledi. Görünüşe göre, harika vurgulama algoritması, yalnızca bir OnInit olduğunu ve sınıfta aşırı yüklenemeyeceğini düşünüyor.

 
Bu sözde kod mu yoksa zaten kullanım için mi? GetData işlevinde, göstergelerin "tutamakları" için "statik" kullanamazsınız ( d_fast_ma, d_slow_ma ), çünkü kullanıcı filtreleme için birkaç "maske" veya başka parametrelerle başka bir şey (örneğin farklı bir sembolde) alır. ). Bazı nesnelerde "tutamaçları" önbelleğe almanız veya (verimliliğe bakmazsanız) "tutamacını" her seferinde yeniden almanız gerekir - terminalin kendisi tarafından eşit parametrelerle önbelleğe alınmaları gerekir.
 
Maxim Kuznetsov :

Elbette, ilerlemeden önce "parti çizgisi"ni ve "hedef-komünizmi"ni kurmak gerekir:

1) Kullanıcının stratejiyi uygulaması için 100 satır yeterlidir. (yorumların, girdilerin ve diğer #özelliklerin yanı sıra).

2) Aynı zamanda, kendisine yeni gelen "varlıkların" (fonksiyonlar/sınıflar/yöntemler/sabitler) sayısı en aza indirilmelidir.

3) kitaplık sayılabilir sayıda dosya içermelidir.

4) GUI için potansiyel olarak uygun

5) eklentilerle genişletilebilir


3) Peki, kitaplığın içerdiği dosya sayısı arasındaki fark nedir? 1, 10, 100, 1000? Her şey bu kütüphaneyi geliştiren kişinin rahatlığı için yapılmalıdır. Her şeyi küçük dosyalara yerleştirmesi uygunsa - lütfen. Her şeyi bir arada kodlamaya alışkınsanız - lütfen. Genel olarak, bir sürü farklı otomatik araçtan bir mega dosya oluşturmak zor değil. Dolayısıyla bu nokta yüzünden ısrar etmeyeceğim.

4) GUI için uygundur - nasıl olduğu tam olarak belli değildir. Kitaplık, yetişkin bir şekildeyse, yalıtılmış bir iş mantığı katmanıdır. Bu katman hiçbir şekilde harici GUI'ye bağlı olmamalıdır. Bu GUI, bu katmana bağlı olmalıdır.

 
Maxim Kuznetsov :
 if (d_fast_ma== 0 ) d_fast_ma= iMA (ea. Symbol ,ea. Period ,FAST_MA_PERIOD, 0 ,FAST_MA_METHOD,FAST_MA_PRICE,shift);
if (d_slow_ma== 0 ) d_slow_ma= iMA (ea. Symbol ,ea. Period ,SLOW_MA_PERIOD, 0 ,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  


Başlangıçta yaklaşımınız tamamen prosedürel: Gördüğüm şey hakkında şarkı söylüyorum. Ve ortalamanın fiyatlara göre değil, hacme veya başka bir göstergeye göre hesaplanması gerekiyorsa? Kullanıcıyı yeniden yeniden yazmaya zorla? Ortalama hesaplama bir algoritmadır. Algoritmayı uygulamak istediğiniz şey verilerdir. Algoritmayı hemen sınırlamak yerine verilerle karıştırıyorsunuz (bu sözde kod için):

 int period_ma = 12 ;
int shift = 3 ;
double fast_ma = SMA( Close , period, shift);

Oops, dizi dizinini unuttum. - Aslında, olmamalı. Algoritmaları boru hatlarında birleştirerek bir halka arabelleğindeki her şeyi hesaplamak gerekir.

 
Maxim Kuznetsov :

https://www.mql5.com/ru/articles/5654 ve Sayın Karputov'un danışmanları ile karşı tez ve polemik olarak

Benim hakkım unutulmadı . Ve boşuna, bir sürü şey var.

 
Vasiliy Sokolov :

Başlangıçta yaklaşımınız tamamen prosedürel: Gördüğüm şey hakkında şarkı söylüyorum. Ve ortalamanın fiyatlara göre değil, hacme veya başka bir göstergeye göre hesaplanması gerekiyorsa? Kullanıcıyı yeniden yazmaya zorla? Ortalama hesaplama bir algoritmadır. Algoritmayı uygulamak istediğiniz şey verilerdir. Algoritmayı hemen sınırlamak yerine verilerle karıştırıyorsunuz (bu sözde kod için):

Oops, dizi dizinini unuttum. - Aslında, olmamalı. Algoritmaları boru hatlarında birleştirerek bir halka arabelleğindeki her şeyi hesaplamak gerekir.

her şeyin büyük bir kısmı bunun için yapılıyor. Böylece her şeydeki her şeyi sayabilirsiniz ve danışmanın kendisi dizileri ve ilişkileri anlar. Bir keresinde MT4'te bir elektronik tablo hesaplayıcısı a la mikro excel yaptım ve görüntü ve benzerlikteki hesaplamaların organizasyonunu aldım.

kullanım durumunda, stil, en yaygın olarak temelde prosedüreldir. Potansiyel kullanıcılar ( acemi programcılar ) aynen böyle yazar.

Neden: