Forumu kirletmemek için herhangi bir acemi sorusu. Profesyonel, kaçırmayın. Sensiz, hiçbir yerde - 6. - sayfa 641

 
simpleton :

Neden bir hatayı taklit edelim?

Hata - sistemin sınırlamaları/arızaları ile ilgili herhangi bir nedenle, algoritmayı çalıştırmanın ve sonucu bazı (elbette sınırlı, ancak - ) garantilerle almanın mümkün olmadığını bildirmek içindir. FillAndPrint() işlevi sadece anlamlıdır ve hatalı bir durumun ne anlama geldiğini ve ne olmadığını gösterir. Bir hata oluştuğunda, bir sonuç üretmeye bile çalışmaz. Herhangi bir hata oluşmazsa, sonuca güvenilebilir. "Hata/hata değil" mantığı bu şekilde oluşturulmalıdır.

Burada algoritmada bir değişiklik de gereklidir: ayrıca ek bir filtre uygulamak gerekir.

Bunu şu şekilde yapmalısınız:

İlk önce, nesnelerin türlerine ve parametrelerine göre "filtreledik", mevcut tüm nesnelerden yalnızca ihtiyacımız olanları seçtik ve ardından ek bir filtre uyguladık. Bir insanın bunu nasıl yapacağı hakkında. Bir insan böyle bir şey yapar, değil mi?

Bu tür her küçük alt görev için ayrı bir işlev kendini önerir.

Çok özel durumlar dışında, örneğin ikiye katlamanız gerekiyorsa, ifadelerde sayı olmamalıdır ve bu ikiye katlama algoritmanın doğasında vardır. Ardından 2 sayısını doğrudan ifadelerde kullanabilirsiniz. Ve diğer benzer çok nadir durumlarda.

Aksi takdirde, anımsatıcılar kullanılmalıdır. İlk olarak, belirli bir yerde neler olduğunun anlaşılmasını büyük ölçüde geliştirirler ve bu nedenle hata yapma olasılığının azaltılmasına katkıda bulunurlar. İkincisi, değerin kendisi tek bir yerde ayarlanır ve gerekirse değiştirmek kolaydır ve sayının algoritmada tekrar tekrar kullanıldığı ve anımsatıcı kullanılmadan kullanıldığı duruma kıyasla hata yapmak imkansız olacaktır. , algoritmanın çeşitli yerlerindeki sayıları düzenlemeniz gerekir.

Çalıştır sonucu:

Hiçbir nesne bulunamadı. Her iki anımsatıcının değerlerini 10 kat artırarak 36000'e (10 saat) çıkaralım ve tekrar çalıştıralım:

Bir eğilim çizgisi filtrelemeyi zaten "geçti". Şimdi ilk anımsatıcının değerini 3600'e geri yükleyelim ve çalıştıralım:

Artık her iki trend çizgisinin de filtrelemeyi "geçtiği" görülebilir. Bu arada, programın sadece bir dalını değil, tüm dallarını (parçalarını) bu şekilde ayıklamanızı tavsiye ederim.

Bir şekilde resmileştirmeye yardımcı olmak için, bunu bu şekilde açıklamaya çalışacağım. Program plana benzer görünüyor.

Planın her bir ana noktası, daha küçük bir alt planın noktalarına bölünebilir. Küçük - daha da küçük. En küçük alt planların öğeleri doğrudan yürütülür.

Her plan, alt plan ve hatta en küçük alt planların öğeleri, programdaki işlevlere karşılık gelir. En küçük alt planlardaki öğeler, yalnızca sistem işlevlerini çağıran veya hatta onları çağırmayan "son" işlevlerine karşılık gelir, örneğin yukarıda tartışılanlarda AddValue() veya DiffInSecs() örnek olarak kullanılabilir. Yukarıdaki alt planların öğeleri, aşağıdaki alt planların öğelerini uygulayan işlevleri çağıran işlevlere karşılık gelir. Yukarıda tartışılanlarda bunlar MassTrendNumber(), AddValueIfFound(), AddValueIfFiltered()'dir. "Düşük seviyeli" fonksiyonlar "yüksek seviyeli" fonksiyonları çağırmamalı ve "yüksek seviyeli" fonksiyonlar genellikle birkaç seviye aşağı atlamamalı, yani fonksiyonları çağırmalı, temelde sadece bir seviye aşağıda olmalıdır. "Düşük seviye" için bu kural "yüksek seviye" için olduğundan çok daha katıdır.

Programlarınızı, böyle bir ağaç yapısıyla birbirine bağlanan (kısa) işlevler biçiminde, içindeki eylemleri, kimin kimi çağırdığı anlamında düzenleyerek oluşturmaya çalışın.

Bu programda, dejenere bir ağaç ortaya çıktı: bir dal birkaç kez "dallanıyor". Ve iki küçük dala değil, bire "dallanır". Ancak mesele şu ki, "üst düzey" işlevler sürekli olarak "düşük düzeyli" işlevler olarak adlandırılır. Bu modifikasyonda, bu yapıya bir seviye daha ekledim, bir tane daha "dallanmamış dal" - AddValueIfFiltered().

Bitmiş kodu gönderiyorum.

Görev: Trend çizgilerini bulma ( OBJ_TREND ), mevcut çubuğa göre fiyat değerlerini bir diziye yazma. Nesne zaman parametrelerinin varlığına ilişkin filtreleme ile (OBJ_TREND).

 #property strict

/******************************************************************************/
bool AddValue( double &array[], const double value) {
   const int size = ArraySize (array);

   if ( ArrayResize (array, size + 1 ) != size + 1 ) {
     return false ; // Ошибка, значение не может быть добавлено к массиву
  }

  array[size] = value; //записываем
   return true ; // Нет ошибки, значение добавлено к массиву
}

/******************************************************************************/
bool AddValueIfFound( double &array[], const string name) {
   const int type = ObjectType(name);

   if (type == OBJ_TREND ) {
     switch (( color )ObjectGet(name, OBJPROP_COLOR )) { // Тип color допустимо использовать в switch
     case Goldenrod:
     case Gainsboro:
     case White:
       if (!AddValueIfFiltered(array, name)) { // Пропускаем через фильтр
         return false ;
      }
    }
  }

   return true ; // Нет ошибки, значение, если найдено, добавлено к массиву
}
/******************************************************************************/
bool MassTrendNumber( double &array[], const bool buy) { // Поиск значения цены трендовой линии, текущего бара, запись в массив. Два массива: masS и masB
   const string subname = (buy ? "uptrendline" : "downtrendline" ); // существует два названия трендовых линий, первое и второе

   if ( ArrayResize (array, 0 ) != 0 ) {
     return false ; // Ошибка, массив не может быть заполнен достоверно
  }

   for ( int i = 0 , limit = ObjectsTotal ( OBJ_TREND ); i < limit + 2 ; i++) {
     if (!AddValueIfFound(array, subname + IntegerToString (i))) {
       return false ; // Ошибка, массив, если и заполнен, то недостоверно
    }
  }
 
   return true ; // Нет ошибки, массив заполнен достоверно
}
/******************************************************************************/
long DiffInSecs( const datetime dt1, const datetime dt2) {
   return dt1 - dt2;
}
/******************************************************************************/
bool AddValueIfFiltered( double &array[], const string name) {
#define MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 3600
#define MAX_SECS_AFTER_PRICE2               3600

   const datetime dt1 = ( datetime )ObjectGet(name, OBJPROP_TIME1);
   const datetime dt2 = ( datetime )ObjectGet(name, OBJPROP_TIME2);
   const datetime dt = TimeCurrent ();
  
   Print ( "name = " , name, // ", dt = ", dt, ", dt1 = ", dt1,"\n", 
   " DiffInSecs = " , DiffInSecs(dt,dt2), " DiffInSecs = " , DiffInSecs(dt2,dt1));

   if ( DiffInSecs(dt,dt2)>MAX_SECS_AFTER_PRICE2 && DiffInSecs(dt2,dt1)> MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 ){
     if (!AddValue(array, ObjectGetValueByShift(name, 1 ))) { // Пытаемся добавить
       return false ; // Ошибка, значение не добавлено
    }
  }

   return true ; // Нет ошибки, значение, если удовлетворило условию фильтра, добавлено к массиву
}

/******************************************************************************/
void FillAndPrint( double &array[], const bool buy) {
   if (MassTrendNumber(array, buy)) {
     const int limit = ArraySize (array);

     Print ( "Найдено объектов: " , limit);

     for ( int i = 0 ; i < limit; i++) {
       Print ( "Price[" , i, "] = " , DoubleToStr(array[i], Digits ));
    }
  } else {
     Print ( "Чёрт!" );
  }
}

/******************************************************************************/
 void OnTick()

//=============================================================================================
//====================================== Линии тренда =========================================
//=============================================================================================
 double masS[]; double masB[];

  Print("Sell:");
  FillAndPrint(masS, false);

  Print("Buy:");
  FillAndPrint(masB, true);
   simpleton Спасибо вам большое, вы за пестовали  меня на ощущения правильного кода!) (Правда я немногое понял))))
 
evillive :

Şimdi 4 işaretim var, eurodolar'da 1 lot 1 puan maliyeti 10 dolar ve bu her zaman böyle olmuştur. Haçlar için maliyet, formülün biraz daha karmaşık olduğu 8 ila 16 arasında olacaktır.

Örneğin, euro sterlin için pazarlama bilgisi 16.984 döndürdü, sterlin döviz kuru dolara = 1.6984, yani 1 euro sterlin puan maliyeti 1 sterlin dolar ile bir sterlin dolar noktasının maliyetinin çarpımıdır, bu her zaman 10.0'dır (100000). *0.0001=10.0 veya 100000 * 0.00010 \u003d 10.0 - istediğiniz gibi).


Tüm bu hesaplamalar, yalnızca hesabınız dolar cinsinden ise doğrudur:

Bu durumda xUSD (EURUSD, GBPUSD vb.) için tickvalue = lot*point = 100000*0.0001 = 10.0

USDx (USDCHF, USDJPY vb.) için tick değeri = lot*puan/Teklif = 100000*0.01/101.93=9.8107

çapraz kurlar için xUSD/yUSD (EURGBP) tick değeri = Bid(yUSD)*lot*puan = 1.6980*100000*0.0001 = 16.98

xUSD/USDy (EURJPY) için tickvalue = lot*point/Bid(USDy) = 100000*0.01/101.91=9.8126 kesişir


Karıştırdığın bir şey! Kodu incelemek için zaman ayırdım, ifadeleri seçtim ve baktım:

   double TV = MarketInfo( Symbol (),MODE_TICKVALUE); 
   string sTV = DoubleToStr(TV, 4 ); 
   Comment ( "TV " ,sTV); //sTV = 1.0/Bid

Daha kolay olamazdı! 10, 16 vb.

 
evillive :

Şimdi 4 işaretim var, eurodolar'da 1 lot 1 puan maliyeti 10 dolar ve bu her zaman böyle olmuştur. Haçlar için maliyet, formülün biraz daha karmaşık olduğu 8 ila 16 arasında olacaktır.

Örneğin, euro sterlin için pazarlama bilgisi 16.984 döndürdü, sterlin döviz kuru dolara = 1.6984, yani 1 euro sterlin puan maliyeti 1 sterlin dolar ile bir sterlin dolar noktasının maliyetinin çarpımıdır, bu her zaman 10.0'dır (100000). *0.0001=10.0 veya 100000 * 0.00010 \u003d 10.0 - istediğiniz gibi).


Tüm bu hesaplamalar, yalnızca hesabınız dolar cinsinden ise doğrudur:

Bu durumda xUSD (EURUSD, GBPUSD vb.) için tickvalue = lot*point = 100000*0.0001 = 10.0

USDx (USDCHF, USDJPY vb.) için tick değeri = lot*puan/Teklif = 100000*0.01/101.93=9.8107

çapraz kurlar için xUSD/yUSD (EURGBP) tick değeri = Bid(yUSD)*lot*puan = 1.6980*100000*0.0001 = 16.98

xUSD/USDy (EURJPY) için tickvalue = lot*point/Bid(USDy) = 100000*0.01/101.91=9.8126 kesişir


borilunad :

Bu doğru değil! Alıntının önemi önemli değil! Ve min.tick değeri cari fiyattan hesaplanmalıdır! TICK_VALUE nedir! Yukarıda benim kodumdan bir örnek var.
 
borilunad :

borilunad :

Bu doğru değil! Alıntının önemi önemli değil! Ve bir min.tick'in maliyeti mevcut fiyattan hesaplanmalıdır! TICK_VALUE nedir! Yukarıda benim kodumdan bir örnek var.

Ve yanlış olan ne? MarketingInfo, yukarıda verdiğim formüllerle elde edilen değerlerin aynısını döndürür. Bu formülleri ben bulmadım, bunlar terminal tarafından TickValue'u hesaplamak için kullanılıyor)))

Pazarlama bilgisinden değer elde etmenin daha uygun olduğu açıktır, ancak kişi tam olarak formülleri veya hesaplama yöntemini sormuştur ve bu nedenle daha yüksektir.

Ve daha önce önemi hakkında yazmıştım, bu önemli değil, çünkü beş basamaklı bir noktada = 10 pip dikkate alınır ve bu 4 basamaklı ile aynı noktadır.

 
evillive :

Ve yanlış olan ne? MarketingInfo, yukarıda verdiğim formüllerle elde edilen değerlerin aynısını döndürür. Bu formülleri ben bulmadım, bunlar terminal tarafından TickValue'u hesaplamak için kullanılıyor)))

Pazarlama bilgisinden değer elde etmenin daha uygun olduğu açıktır, ancak kişi tam olarak formülleri veya hesaplama yöntemini sormuştur ve bu nedenle daha yüksektir.

Ve daha önce önemi hakkında yazmıştım, bu önemli değil, çünkü beş basamaklı bir noktada = 10 pip dikkate alınır ve bu 4 basamaklı ile aynı noktadır.


Evet, MarketInfo( Symbol (),MODE_TICKVALUE) = 1.0/Bid; Belki sadece eurodolar için, başkalarına püskürtmem!
 
borilunad :

Evet, MarketInfo( Symbol (),MODE_TICKVALUE) = 1.0/Bid; Belki sadece eurodolar için, başkalarına püskürtmem!

Bu, sertifikada verilen tanıma göre eurodolar için yanlıştır.

MODE_TICKVALUE

on altı

Mevduat para birimi cinsinden enstrümanın fiyatındaki minimum değişikliğin tutarı


Ve bu çarpma anlamına gelir

MODE_POINT

on bir

Teklif para biriminde nokta boyutu. Mevcut takım için önceden tanımlanmış değişken Noktada saklanır


üzerinde

MODE_LOTSIZE

on beş

Araç temel para birimi cinsinden sözleşme boyutu


Eh, tabii ki, eğer avro cinsinden bir hesabınız varsa, o zaman avrodan dans etmeniz gerekir, ancak hala dolar hesabı olan (ve çoğu) tüccarlar için yukarıdaki formüller geçerlidir . Ve ana ve en çok işlem gören çiftler ABD dolarına dayandığından, en sık bu formüller kullanılır.

 
evillive :

Bu, yardımda verilen tanıma göre yanlıştır.

MODE_TICKVALUE

on altı

Mevduat para birimi cinsinden enstrümanın fiyatındaki minimum değişikliğin tutarı


Ve bu çarpma anlamına gelir

MODE_POINT

on bir

Teklif para biriminde nokta boyutu. Mevcut takım için önceden tanımlanmış değişken Noktada saklanır


üzerinde

MODE_LOTSIZE

on beş

Araç temel para birimi cinsinden sözleşme boyutu


Tabii ki, eğer avro cinsinden bir hesabınız varsa, o zaman avrodan dans etmeniz gerekir, ancak çoğu tüccarın hala dolar cinsinden bir hesabı var.


O zaman özel bir durumum var, ama benim için avro bölgesinde yaşamak, tüm hesaplamaları avro cinsinden yapmak daha uygun!
 

Beyler, bana aşağıdaki gösterge için bir kod örneği söyleyin. Kaç tane arabelleğe ihtiyaç olduğunu, ne tür bir görüntülemenin ve nerede ve hangi özellikleri kaydetmeleri gerektiğini anlayamıyorum.

Gösterge şöyle:

1 Segmentler, her üç çubuktan birinin alt ucunu ve komşu çubuğu birbirine bağlar. Kırmızı çizgi.

2 Segment, her 5. çubuğun yükseklerini ve komşu olanını birbirine bağlar. Çizgi mavi.

Ana şey: segmentler hiçbir şekilde kesişmez. Her bölümün başı ve sonu diğer bölümlerden bağımsızdır.

Gösterge, her segmentin başlangıç ve bitiş değerlerini hesaplar. Koşullara bağlı olarak, farklı renklerde boyanmaları gerekir.

Kabaca nasıl görünmesi gerektiği


 

Ve başka bir soru.

Debug modunda gösterge ile çalışamamanız normal mi?

Program kesme noktasına ulaştığında, MT4 terminali donuyor ve pencere beyaza dönüyor (XP'de) bu nedenle grafikte ne çizildiğini görmek mümkün değil

 
Top2n :

Bitmiş kodu gönderiyorum.

Görev: Trend çizgilerini (OBJ_TREND) bulmak, mevcut çubuğa göre fiyat değerlerini bir diziye yazmak. Nesne zaman parametrelerinin varlığına göre filtrelenir (OBJ_TREND).

simpleton : Çok teşekkür ederim , doğru kodu hissetmemi sağladınız!) (Doğru, az anladım))))

Eğer antrenman yaparsanız, anlayış giderek daha fazla gelecektir. Konsantrasyon ve dikkat gerektirir. Program algoritması büyük bir fonksiyona yayıldığında, onu konsantrasyon ve dikkatle uygulamak zordur - çok fazla bağlantı oluşur. Program işlevsel olarak tamamlanmış parçalara (küçük işlevler) bölünmüşse, her bir küçük işlev için bunu yapmak çok daha kolaydır. Ve böylece her fonksiyon düzeyinde. Bu arada:

   if ( DiffInSecs(dt,dt2)>MAX_SECS_AFTER_PRICE2 && DiffInSecs(dt2,dt1)> MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 ){
     if (!AddValue(array, ObjectGetValueByShift(name, 1 ))) { // Пытаемся добавить
       return false ; // Ошибка, значение не добавлено
    }
  }
Muhtemelen, anımsatıcıyı MAX_SECS_AFTER_PRICE2 olarak adlandırdım (çünkü ilk başta koşulun tersine çevrilmesi gerektiğini anladım), anlama göre muhtemelen MIN_SECS_AFTER_PRICE2, yani izin verilen minimum, maksimum değil.
Neden: